2011-04-21 67 views
0

我正在通过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中启动的。

回答

1

找到了一个方法。

原来,当你调用

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 
相关问题