繁体   English   中英

Jooq 一次将 one2one 和 one2many 关系数据插入到 2 个表中。 如何处理问题和回滚

[英]Jooq insert one2one and one2many relational data into 2 tables at once. How to deal with issues and rollback

铁 model

class Author {
  id, name
}

class Book {
  id, title, author
}


create table author (
    id bigint not null auto_increment,
    name varchar,
    CONSTRAINT author_pk PRIMARY KEY (id),
);
create table book (
    id bigint not null auto_increment,
    title varchar,
    author_id bigint,
    CONSTRAINT book_pk PRIMARY KEY (id),
    CONSTRAINT book_fk_author FOREIGN KEY (author_id) REFERENCES author (id) ON DELETE NO ACTION ON UPDATE NO ACTION
)

如何在jooq中一次插入? 如果某些查询失败,如何处理回滚? 它必须在我这边编程吗? 我在文档中找不到关于这种情况的消息:(

我应该像手动一样:

  1. 按名称在数据库中查找作者 ID
  2. 如果作者不存在插入新作者
  3. 插入带有作者 ID 的书
  4. 如果书籍插入失败,那么如果这次插入则删除作者?

如何处理? 你有这方面的例子吗?

编辑:我使用 h2 数据库

数据库中的所有更改都是事务性的。

如果 on 操作失败,您可以回滚事务,然后数据库中将没有任何数据。 所以没有必要删除一些东西。

请阅读文档中有关事务管理的部分: https://www.jooq.org/doc/3.14/manual-single-page/#transaction-management

Simon已经为您提供了有关逻辑事务性的反馈。 您的 4 个步骤可以编码如下(假设您使用的是代码生成器):

// You probably have some DSLContext injected to your repository/dao/whatever somewhere
DSLContext ctx = ...

// 4. Start the transaction to make the contents atomic and roll back on failure
// In order to use a transactional configuration and DSLContext, make sure you don't use
// the "outer" DSLContext, which, depending on its Configuration might not be 
// transactional. E.g. it isn't transactional when it references a DataSource. It might
// be transactional (by accident), if it wraps a JDBC Connection.
ctx.transaction(c -> {

    // 1. try to find the author by ID. Alternatively, write a query
    AuthorRecord author = c.dsl().fetchOne(AUTHOR, AUTHOR.ID.eq(id));

    // 2. If the author wasn't found, create it
    if (author == null) {
        author = c.dsl().newRecord(AUTHOR);
        author.setName(name);

        // 2. This will store the author and by default, automatically fetch the 
        // generated ID
        author.store();
    }

    // 3. Insert the book with the previously fetched author ID
    BookRecord book = c.dsl().newRecord(BOOK);
    book.setAuthorId(author.getId());
    book.setTitle(title);
    book.store();
}

Instead of using the jOOQ transaction API, of course, you can use any other means of providing transactionality to your code, including Spring, Java EE, or JDBC directly.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM