【发布时间】:2015-02-11 12:54:35
【问题描述】:
如果在提交过程中与数据库资源的连接丢失,这可能导致提交失败然后回滚失败,事务是否可能部分提交?这似乎发生在我的案例中,但希望社区能更清楚地说明这一点。 HibernateTransactionManager 和 Oracle 正在与 JDBC 驱动程序一起使用。
【问题讨论】:
标签: oracle hibernate jdbc transactions
如果在提交过程中与数据库资源的连接丢失,这可能导致提交失败然后回滚失败,事务是否可能部分提交?这似乎发生在我的案例中,但希望社区能更清楚地说明这一点。 HibernateTransactionManager 和 Oracle 正在与 JDBC 驱动程序一起使用。
【问题讨论】:
标签: oracle hibernate jdbc transactions
添加答案,因为我可以找到发生部分提交的原因。正在使用的 jdbc 连接池上设置了属性以删除废弃的连接。在从池中删除此类连接时,将对此类连接调用 close() ,这将导致提交当时正在使用这些连接的事务(从应用程序的角度来看不会被放弃)。一种解决方案是拦截此类关闭调用并回滚连接或适当处理
【讨论】:
否(除非 Oracle 中存在严重错误,或者除非我们谈论的是分布式事务)。
如果客户端与数据库之间的连接丢失,则数据库可能从未收到提交事务的请求。在这种情况下,一旦数据库发现客户端死机(这可能需要一些时间),事务就会回滚。如果连接丢失,可能是数据库成功提交,但客户端始终没有收到提交成功的通知。
如果我们谈论的是分布式事务,则事务可能在一个(或多个)分布式节点上仍然存在疑问。如果是这种情况,事务将出现在事务仍待处理的节点上的dba_2pc_pending 中。但它不会在任何节点上部分提交。
如果我不得不猜测,如果您看到“部分提交”的内容,我敢打赌问题在于您的事务边界不正确,并且您在某处有一些正在提交的代码(隐含或明确)在您不期望的地方。
【讨论】:
connection.close,这意味着与数据库的连接不会丢失 - 您显然仍然可以调用close 方法。如果您有代码明确关闭连接,而其他步骤应该是事务的一部分,那不是“部分提交”,这是您的应用程序中的一个错误,导致您的事务边界不正确。
connection.close,客户端将发出commit 的事实是无关紧要的。届时将没有与数据库的连接来传输提交事务的请求。