有没有办法确定JDBC事务是否有效?
问题描述:
我正在通过JDBC调用几个SQLServer 2008存储过程。有没有办法确定JDBC事务是否有效?
我希望所有这些proc调用都是同一事务的一部分。
在Java方面,我有以下的等价:
con.setAutoCommit(false);
boolean hasFailed = true;
try
{
... call PROC_1
... call PROC_2
con.commit();
hasFailed = false;
}
finally
{
if (hasFailed)
{
con.rollback();
}
con.setAutoCommit(true);
}
在PROC_1我有一个交易的后卫,只有如果没有有效的交易开始一个新的事务。
防护是通过检查@@ TRANCOUNT的值
declare @owns_transaction int = 0
begin try
if @@TRANCOUNT = 0
begin
begin transaction
set @owns_transaction = 1
end
... do work
if @owns_transaction = 1
begin
commit transaction
set @owns_transaction = 0
end
end try
begin catch
if @owns_transaction = 1
begin
rollback transaction
set @owns_transaction = 0
end
... handle error
end catch
然而,当我进入PROC_1的@@ TRANCOUNT仍为0实现的,所以它开始一个新的事务,我认为它可能有一些可怕的后果。
我试过使用XACT_STATE(),但它也返回0的结果,这意味着'没有活动的用户事务为当前请求',并根据此我必须启动手动事务以及。
我做错了什么?
顺便说一句,我认为SQLServer确实知道它是在事务中,因为如果我给transaction
语句添加一个名称,它会在rollback
中回避它无法用该名称回滚事务。这给了我一个线索,即PROC_1中没有启动TOP-LEVEL事务,但确实是在JDBC中启动的。
答
找到了一个方法。
原来,当你调用
con.setAutoCommit(false)
相当于设置IMPLICIT_TRANSACTIONS选项的连接上,这样
SET IMPLICIT_TRANSACTIONS ON;
然后你可以检查与@@ OPTIONS功能的帮助下隐含交易状态:
if ((@@OPTIONS & 2) != 2) and (@@TRANCOUNT = 0)
begin
select 'No transaction'
end
else begin
select 'Already in transaction'
end