JDBC commit():幕后发生了什么?

时间:2011-03-09 16:15:16

标签: sql-server jdbc transactions

我正在帮助解决僵局。环境:Tomcat 5.5,Java 5,Microsoft SQL Server 2008,jTDS(替换旧驱动程序)。我们有一个传统的连接池。

数据库代码始终遵循以下方案:

connection = connectionPool.getConnection(); // 1
boolean previousAutoCommitStatus = connection.getAutoCommit(); // 2
connection.setAutoCommit(false); // 3

// ... use the connection ...
// execute prepared statement 4
// execute prepared statement 5
// execute prepared statement 6

connection.commit(); // 7
connection.setAutoCommit(previousAutoCommitStatus); // 8
connectionPool.releaseConnection(connection); // 9

虽然我们捕获了这个错误(原谅:软件缺陷)但我想知道:驱动程序是如何工作的?我的猜测:无论我在(3)和(7)之间做什么都由驱动程序/ DBMS排队。只有当我connection.commit() DBMS开始一个新事务时,才获取操作所需的每个锁(我希望它足够智能锁定较小的可能对象集),执行语句并释放锁,从而关闭事务。

或者,只要我执行预准备语句,DBMS就会锁定表吗?

编辑:我想要了解的是“commit()”是否在一组以“begin trans / lock table”开头并以“commit / unlock table”结尾的SQL语句中翻译或如果任何Java executeStatement()立即获得锁定。

TIA

4 个答案:

答案 0 :(得分:5)

如果您对内幕细节感兴趣, 在连接上发送SQLServer JDBC实现

发出以下命令

IF @@TRANCOUNT > 0 COMMIT TRAN

@@ TRANCOUNT = 0 - 没有开放交易 @@ TRANCOUNT = 1 - 1个开放交易 @@ TRANCOUNT = 10 - 10开放交易

将自动提交设置为false时,

set implicit_transactions on

这些是MS SQLServer特定命令。

答案 1 :(得分:1)

根据this resource,只要您拨打setAutocommit(false);

,交易就会启动

我认为它可能仍然依赖于驾驶员,但这将是典型的。另请参阅MSDN,其中也相同。

//Switch to manual transaction mode by setting
//autocommit to false. Note that this starts the first 
//manual transaction.
con.setAutoCommit(false);

答案 2 :(得分:1)

connection.setAutoCommit(false); 

在数据库服务器上触发“BEGIN TRAN”和

connection.commit();

会触发“COMMIT TRAN”

如果要防止这两个语句之间的锁定,请将连接的隔离级别设置为“Read Uncommited”。在这种情况下,您必须确保它是可接受的。

setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

答案 3 :(得分:0)

完全的内容完全取决于驱动程序的实现,因此您需要查看正在使用的驱动程序的文档以获得明确的答案。

setAutoCommit(false)不一定在数据库上开始事务,并且语句不一定在数据库上执行,甚至在您调用代码中的execute函数时获取锁定,正如您所推测的那样。话虽这么说,据我所知,共享(读)锁通常是在执行语句时获取的;调用commit时更新锁。您可能遇到转换死锁(当多个语句的读锁定在等待转换为写锁时发生),我会检查您的更新语句是否在其中嵌套了可能导致此类锁定的选择。