【发布时间】:2015-08-26 20:24:21
【问题描述】:
当我用 c# 更新 MS SQL 2005 数据库时,我想使用嵌套的 sql 事务。我试过以下代码:
try
{
conn.Open();
cmd.Connection = conn;
cmd.Transaction = conn.BeginTransaction();
////BEGIN TRAN
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "storeprocname";
cmd.Parameters.Add("@xxx", SqlDbType.VarChar, 50);
cmd.Parameters["@xxx"].Value = "string_value";
cmd.ExecuteNonQuery();
if (<sql can do>)
{
cmd.Transaction.Commit();
}
else
{
cmd.Transaction.Rollback();
}
}
catch (Exception ex)
{
cmd.Transaction.Rollback();
}
上面的代码打开一个事务并将一些数据放入sql中。如果我输入的数据正确,它可以正常运行。但如果不是,它会捕获以下与我预期完全不同的错误,即:
[System.Data.SqlClient.SqlException] = {"无法回滚 updatetransport。找不到该名称的事务或保存点。\r\nEXECUTE 后的事务计数表明缺少 COMMIT 或 ROLLBACK TRANSACTION 语句。以前的计数= 1,当前计数 = 2。"}
代码是sql:
begin tran updatetransport
update db set xxx=@xxx where xxx=@xxx
if @@rowcount < 1 or @@error <> 0 -- no record updated
begin
rollback tran updatetransport /*updatran is the name of transaction*/
return -1 --fail
end
else
begin
commit tran updatetransport
return 0 --success
end
似乎 sql server 正在自动回滚事务。当我试图回滚它时抛出错误。但是,当我尝试按以下方式修改代码时,仍然没有运气。我错过了什么吗?
我在开始交易后声明了@tcount =@@TRANCOUNT。
if @tcount = @@TRANCOUNT
begin
rollback tran updatetransport
end
【问题讨论】:
-
避免嵌套事务。因为他们不是。我已经编码了很长时间,并且从不需要代码中的嵌套事务。你认为你需要一个这一事实表明你的设计可能是错误的。
-
您的存储过程中已经有一个事务,在c#代码中不需要另一个。
-
我明白这是多余的,但有时可能有两个人处理sql和c#。在某些想法在逻辑上可行的情况下,这也令人沮丧,但它的发生并不像预期的那样。对与错必须记录在案。
标签: c# sql sql-server transactions