问题描述
我在示例程序中执行此操作:
SELECT @@TRANCOUNT; //COUNT IS 0
SELECT * FROM CUBE; //EXECUTE SELECT STATEMENT
SELECT @@ TRANSCOUNT; // COUNT IS Now 1
我不明白,为什么 sql Server 会为 SELECT 语句创建一个额外的事务?如果 CREATE / UPDATE / DELETE 语句出现,我们的业务逻辑依赖于调用 COMMIT / ROLLBACK?但在这种情况下,由于事务计数为 1,sql Server 不会释放此连接实例持有的资源。
我们可以做些什么来避免在 SELECT 语句的情况下创建事务?
-- 用于执行此案例的代码块:
try (Connection connection = createNewConnection()) {
connection.prepareStatement("SET IMPLICIT_TRANSACTIONS OFF").execute();
connection.setAutoCommit(false);
System.out.println("Transaction Count [BEFORE] " + transactionCount(connection));
PreparedStatement preparedStatement = connection.prepareStatement("SELECT COUNT(*) FROM CONNECTIONMetaDATA");
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next())
System.out.println("Connection Count : " + resultSet.getInt(1));
System.out.println("Transaction Count [AFTER] " + transactionCount(connection));
} catch (Exception e) {
e.printstacktrace();
}
public static int transactionCount(Connection connection) throws sqlException {
ResultSet resultSet = connection.prepareStatement("SELECT @@TRANCOUNT;").executeQuery();
return resultSet.next() ? resultSet.getInt(1) : 0;
}
private static Connection createNewConnection() throws sqlException,ClassNotFoundException {
String driver = "com.microsoft.sqlserver.jdbc.sqlServerDriver";
Class.forName(driver);
String url = "jdbc:sqlserver://DT01070611:1433;databaseName=BI711QA9;";
Properties props = new Properties();
props.put("username","BI711QA9");
props.put("user","BI711QA9");
props.put("password","BI711QA9");
return DriverManager.getConnection(url,props);
}
输出:
Transaction Count [BEFORE] 0
Connection Count : 2
Transaction Count [AFTER] 1
上次更新:似乎 setAutoCommit(false) 正在将 SET IMPLICIT_TRANSCATION 触发为 ON。
添加以下块以获取 IMPLICIT TRANSACTION 的当前值
private static String getImplicitTransactionValue(Connection connection) throws sqlException {
try(PreparedStatement preparedStatement = connection.prepareStatement("DECLARE @IMPLICIT_TRANSACTIONS VARCHAR(3) = 'OFF';" +
"IF ( (2 & @@OPTIONS) = 2 ) SET @IMPLICIT_TRANSACTIONS = 'ON'; " +
"SELECT @IMPLICIT_TRANSACTIONS AS IMPLICIT_TRANSACTIONS;");){
ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
return resultSet.getString(1);
}
return "";
}
并修改代码以显示每一步后的结果(此处不粘贴该代码) 和输出是:
AT the start: Implicit Transaction Value: OFF
After setting off explicitly: Implicit Transaction Value: OFF
After Auto Commit: Implicit Transaction Value: ON
Transaction Count [BEFORE] 0
Connection Count : 2
Transaction Count [AFTER] 1
Implicit Transaction Value: ON
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)