jooq 事务
响应式编程是新的流行语,它实质上仅表示异步编程或消息传递。
事实是,函数语法在很大程度上有助于构建异步执行链,而今天,我们将看到如何使用jOOQ和新的CompletableFuture API在Java 8中做到这一点。
实际上,事情很简单:
// Initiate an asynchronous call chain
CompletableFuture
// This lambda will supply an int value
// indicating the number of inserted rows
.supplyAsync(() -> DSL
.using(configuration)
.insertInto(AUTHOR, AUTHOR.ID, AUTHOR.LAST_NAME)
.values(3, "Hitchcock")
.execute()
)
// This will supply an AuthorRecord value
// for the newly inserted author
.handleAsync((rows, throwable) -> DSL
.using(configuration)
.fetchOne(AUTHOR, AUTHOR.ID.eq(3))
)
// This should supply an int value indicating
// the number of rows, but in fact it'll throw
// a constraint violation exception
.handleAsync((record, throwable) -> {
record.changed(true);
return record.insert();
})
// This will supply an int value indicating
// the number of deleted rows
.handleAsync((rows, throwable) -> DSL
.using(configuration)
.delete(AUTHOR)
.where(AUTHOR.ID.eq(3))
.execute()
)
// This tells the calling thread to wait for all
// chained execution units to be executed
.join();
这里真的发生了什么? 没有什么不寻常的。 有4个执行块:
- 插入新作者的
- 再次获取同一作者的
- 重新插入新获取的AUTHOR的对象(引发异常)
- 一种忽略引发的异常并再次删除AUTHOR的方法
最后,当执行链建立时,调用线程将使用CompletableFuture.join()
方法加入整个链,该方法与Future.get()
方法基本相同,不同之处在于它不会引发任何已检查的异常。
与其他API进行比较
诸如Scala的Slick之类的其他API也通过“标准API”实现了类似的操作,例如对flatMap()
调用。 我们目前不会模仿这样的API,因为我们相信新的Java 8 API对于本机Java讲者来说将变得更加惯用。 具体来说,在执行SQL时,正确实现连接池和事务至关重要。 异步链接的执行块的语义以及它们与事务的关系非常微妙。 如果您希望一个事务跨越多个这样的块,则必须自己通过jOOQ的Configuration
及其包含的ConnectionProvider
对其进行编码。
阻止JDBC
显然,此类解决方案始终存在一个障碍,那就是JDBC本身-很难将其转变为异步API。 实际上,很少有数据库真正支持异步查询执行和游标,因为大多数情况下,单个数据库会话一次只能由单个线程用于单个查询。
jooq 事务