2011-04-21 20 views
0

私はJDBCを介していくつかのSQLServer2008ストアドプロシージャを呼び出しています。JDBCトランザクションが有効かどうかを判断する方法はありますか?

私はこれらのproc呼び出しをすべて同じトランザクションの一部にしたいと思います。 PROC_1で

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); 
} 

は私が有効なトランザクションがない場合のみ、新しいトランザクションを開始トランザクションガードを持っている:

は、Java側では、私は、次のと同等のものを持っています。

ガードは、私がPROC_1を入力したときに@@ TRANCOUNTはまだ0である、

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 

しかし@@ TRANCOUNTの値をチェックすることで実装されているので、新しいトランザクションを開始し、私はそれはいくつかを持っているかもしれないと思います後で悲惨な結果になる。

私はXACT_STATE()を使用しようとしましたが、「現在の要求に対してアクティブなユーザートランザクションがありません」という結果も0を返します。これに応じて手動トランザクションを開始する必要があります同じように。

何か間違っていますか?

transactionステートメントに名前を追加すると、rollbackにその名前でトランザクションをロールバックできないため、SQLServerはトランザクション中であることを知っていると思います。これにより、TOP-LEVELトランザクションがPROC_1で開始されていないことがわかりますが、実際にはJDBCで開始されています。

答えて

1

方法が見つかりました。

あなたは

con.setAutoCommit(false) 

を呼び出すとき

が判明その後、あなたはOPTIONS機能@@の助けを借りて、暗黙的なトランザクションの状態を確認することができ、この

SET IMPLICIT_TRANSACTIONS ON; 

のように、接続にIMPLICIT_TRANSACTIONSオプションを設定することと同じです:

if ((@@OPTIONS & 2) != 2) and (@@TRANCOUNT = 0) 
begin 
    select 'No transaction' 
end 
else begin 
    select 'Already in transaction' 
end 
関連する問題