2011-04-21 108 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 
相關問題