トランザクションにラップされた2つのストアドプロシージャがあります。いろいろな理由から、データベース内ではなく、アプリケーションコード内でトランザクションを処理する必要があります。理にかなってSqlTransactionのロールバックに関する例外処理
Error message from raiserror within stored procedure.
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0.
:保存されprocsのの1にエラーが発生した場合
try
{
using (SqlConnection conn = Connection())
{
conn.Open();
using (SqlTransaction sqlTrans = conn.BeginTransaction())
{
try
{
using (SqlCommand cmd1 = new SqlCommand("Stored_Proc_1", conn, sqlTrans))
{
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.ExecuteNonQuery();
}
using (SqlCommand cmd2 = new SqlCommand("Stored_Proc_2", conn, sqlTrans))
{
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.ExecuteNonQuery();
}
sqlTrans.Commit();
}
catch
{
sqlTrans.Rollback();
throw;
}
}
conn.Close();
}
}
catch (SqlException ex)
{
// exception handling and logging code here...
}
、例外メッセージは、私のようなルックスを見ています:現時点では
、私のコードは次のようになりますなぜなら、最初のキャッチでは、トランザクションはまだロールバックされていないからです。
私は例外処理コードのためにがトランザクションをロールバックしているので、私はこの件に興味がありません。 これを達成するためにコードを再構築する方法はありますか?
編集:私は私のストアドプロシージャの外のトランザクション処理を撮影したし、それはそう :
create proc Stored_Proc_1
as
set nocount on
begin try
begin transaction
raiserror('Error raised by Stored_Proc_1', 16, 1)
commit
end try
begin catch
if (@@trancount > 0) rollback
declare @ErrMsg nvarchar(4000), @ErrSeverity int, @ErrProc sysname, @ErrLine varchar(10)
select @ErrMsg = ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY(), @ErrProc = ERROR_PROCEDURE(), @ErrLine = ERROR_LINE()
-- log the error
-- sql logging code here...
raiserror(@ErrMsg, @ErrSeverity, 1)
end catch
がUPDATE:
が私の保存されてprocsの基本的な構造はこのようになります問題を解決した明らかに私はそれを間違っていた - でも、私はそれを正しく行う方法を知りたいです。ストアドプロシージャのトランザクションを最適なソリューションから削除していますか?
あなたのコメントのおかげで、私は自分の格納されたprocsが間違っているとは思わない - 私は基本的な構造を含むように質問を更新しました。 – kristian
待って、私はあなたが言っていることを見ていると思います.C#コードはトランザクションが存在すると予想していますが、SQLコードはそれをロールバックしていますか? – kristian
まさに...行 "if(@@ trancount> 0)rollback"は特別なものです... **トランザクションが**作成されたかどうかを追跡するフラグを設定する必要があります。オープンな取引。 –