我们运行一个用Java编写的网站,该网站使用JDBC和jTDS来访问SQL Server数据库。
我们的数据库包含一个复杂的存储过程,通常需要10分钟才能运行。如果我们直接执行存储过程(例如从SQL Server Management Studio中执行),则该存储过程可以正常工作,因为它不在事务中运行。但是,如果我们使用jTDS执行它,那么它将锁定整个网站10分钟。发生这种情况是因为jTDS在事务中运行它,因此所有网站请求都处于等待状态,以等待事务完成。
例如,以下内容因交易而锁定了网站:
Connection connection = DriverManager.getConnection("jdbc:jtds:sqlserver://example/example");
CallableStatement callableStatement = connection.prepareCall("exec dbo.procTest");
callableStatement.execute();
有没有什么方法可以使我们使用JDBC / jTDS运行存储过程而不在事务中运行存储过程?
请注意,在jTDS连接上调用此命令无效:
connection.setTransactionIsolation(Connection.TRANSACTION_NONE);
抛出一个异常,指出jTDS不支持Connection.TRANSACTION_NONE参数。
编辑:我可能会更好地问这个问题:核心问题不是事务本身,问题是事务导致数据库锁定被保持10分钟。我需要摆脱交易,或者需要在交易期间释放锁。
最佳答案
在我们的例子中,必须调用StoredProcedure,当从jtds调用时抛出了异常:
无法在事务内执行备份或还原操作。
我在https://communities.bmc.com/docs/DOC-66239中找到的内容
是在执行调用之前需要加上“ SET IMPLICIT_TRANSACTIONS OFF;”吗?
这是基于春季的代码段的样子:
try {
jdbcTemplate.getJdbcOperations.execute("SET IMPLICIT_TRANSACTIONS OFF;")
//noinspection ConvertExpressionToSAM // we have 1.6 code version
jdbcTemplate.getJdbcOperations.call(new CallableStatementCreator {
override def createCallableStatement(con: Connection): CallableStatement = {
val callableStatement = con.prepareCall(
s""" EXEC dbo.RestoreLatestCopy
| @ID = ?
|""".stripMargin)
callableStatement.setInt(1, getMappedRestoreId(fromDbName))
callableStatement
}
}, parameters ++ rsParams)
} catch {