使用 JDBI 3.1.0。
当使用 autocommit = false 时,JDBI 将无法打开一个事务,它会抛出一个异常说该事务已经打开。
从我调试的内容来看,问题似乎出在 LocalTransactionHandler 类中。
public boolean isInTransaction(Handle handle)
{
return !handle.getConnection().getAutoCommit();
}
public <R, X extends Exception> R inTransaction(Handle handle,
HandleCallback<R, X> callback) throws X
if (isInTransaction(handle)) {
throw new IllegalStateException("Already in transaction");
}
如果自动提交为真,则不会发生这种情况。
还有什么办法可以帮助您解决这个问题?
谢谢
这是 JDBC 的一个特性:如果将 auto-commit 设置为 false,则下一个数据库操作将隐式启动一个事务。
https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
如果您使用 Jdbi 方法来管理事务,Jdbi 希望成为该自动提交属性的仲裁者。 否则我们无法知道您是否正在手动管理自动提交,还是不正确地使用 begin() / commit() / rollback() 方法。
我们有一个未解决的问题,试图使用保存点来允许“子事务”。 见#937
虽然我使用 auto-commit=true 没有任何问题,但这种行为很奇怪,因为开发人员可能无论如何都不正确地调用 begin() / commit() / rollback() 。
我的主要问题是该行为未记录在案,我只是通过调试才弄清楚。 此外,我正在将应用程序从休眠状态迁移到 JDBI,在休眠状态下,他们建议使用 auto-commit=false。
此外,从 API 的角度来看,使用“子事务”不会令人困惑。 隐式而不是显式?
虽然我使用 auto-commit=true 没有任何问题,但这种行为很奇怪,因为开发人员可能无论如何都不正确地调用 begin() / commit() / rollback() 。
我们实际上在handle.close()
中有一个检查,如果存在未解决(即未提交或回滚)的事务,则会抛出异常。 您可以禁用该检查,但默认行为是捕获您使用 API 不当、自动回滚事务并抛出异常,指出事务未正确终止。
我的主要问题是该行为未记录在案,我只是通过调试才弄清楚。
这还算公平。 我们在 v3 版本中投入了大量工作来改进文档,但显然还有改进的空间。
如果您愿意提交包含您希望已经在那里的文档的拉取请求,那将非常有帮助。 我们试图做到彻底,但是当您在代码中使用一段时间后,可能很难看到它对新手的看法。
此外,我正在将应用程序从休眠状态迁移到 JDBI,在休眠状态下,他们建议使用 auto-commit=false。
我同意设置auto-commit=false
是 Hibernate / JPA 项目的最佳实践。 您想使用 Hibernate 设置它的原因是,在 Session 中检索到的所有记录都来自相同的数据库状态。
Jdbi 不使用会话——我们直接使用数据库事务。 使用 Jdbi,您可以读取实时数据,或使用事务以便连续读取来自一致的数据库状态——由您自行决定。 如果您的用例需要,您还可以在同一个连接上执行多个独立事务。 所以auto-commit=false
推荐在 Jdbi 中有点不合时宜。
此外,从 API 的角度来看,使用“子事务”不会令人困惑。 隐式而不是显式?
一些 JDBC 驱动程序支持事务中的“保存点”(也称为“检查点”)的概念。 通过将嵌套事务映射到这些保存点,它将提供一种无需提交或回滚整个事务即可自动提交或回滚操作子集的方法。
我想我们可以提供一个inSavepoint(String name, TransactionCallback)
来自动创建保存点,并根据回调是否抛出异常来释放(相当于提交)或回滚保存点。
谢谢你的时间!
我本周末提交了文档 PR。
最有用的评论
谢谢你的时间!
我本周末提交了文档 PR。