У меня есть две хранимые процедуры, которые я хочу выполнить, завернутые в транзакцию. По разным причинам мне нужно обрабатывать транзакции в коде моего приложения, а не в базе данных.
На данный момент мой код выглядит так:
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...
}
Когда один из сохраненных процессов вызывает ошибку, я вижу сообщение об исключении:
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.
Это имеет смысл, потому что при первом улове транзакция еще не была отменена.
Но я хочу "чистую" ошибку (без сообщения о количестве транзакций - мне это не интересно, потому что я am откатываю транзакцию) для моего кода обработки исключений.
Есть ли способ, которым я могу реструктурировать свой код для достижения этой цели?
EDIT:
Базовая структура моих хранимых процедур выглядит следующим образом:
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:
Я убрал обработку транзакций из своих хранимых процедур, и это, похоже, решило проблему. Очевидно, я делал это неправильно, но я все еще хотел бы знать, как сделать это правильно. Является ли удаление транзакций из хранимых процедур лучшим решением?