我的应用程序中有一次出现了以下错误。
此SQLTransaction已完成,不再可用。
堆栈跟踪附在下面-它是关于Zombie Check和Rollback的。
代码中的错误是什么?
注意:此错误只出现一次。
更新
来自MSDN - SqlTransaction.Rollback方法
如果连接终止或事务已在服务器上回滚,回滚将生成InvalidOperationException。
来自僵尸检查事务错误
我看到这个错误出现在各种应用程序中的最常见的原因之一是,在我们的应用程序中共享 SqlConnection。
码
public int SaveUserLogOnInfo(int empID)
{
int? sessionID = null;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = null;
try
{
transaction = connection.BeginTransaction();
sessionID = GetSessionIDForAssociate(connection, empID, transaction);
//Other Code
//Commit
transaction.Commit();
}
catch
{
//Rollback
if (transaction != null)
{
transaction.Rollback();
transaction.Dispose();
transaction = null;
}
//Throw exception
throw;
}
finally
{
if (transaction != null)
{
transaction.Dispose();
}
}
}
return Convert.ToInt32(sessionID,CultureInfo.InvariantCulture);
}堆栈跟踪

参考
发布于 2013-03-08 12:18:02
您应该将一些工作留给编译器来为您将其包装在try/catch/finally中。
此外,如果在Rollback阶段出现问题,或者如果到服务器的连接中断,您应该期望Commit偶尔会抛出异常。因此,您应该将其包装在try/catch中。
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}这完全是从用于回滚方法的MSDN文档页复制的。
我看到你担心你会有僵尸交易。万一你粘上了,听起来不像你有问题。你的交易已经完成,你不应该再和它有任何关系了。如果你持有它,删除对它们的引用,并忘记它。
来自MSDN - SqlTransaction.Rollback方法
如果连接终止或事务已在服务器上回滚,回滚将生成InvalidOperationException。
重新抛出一个新异常,告诉用户数据可能没有保存,并要求她刷新和检查数据。
发布于 2013-03-08 12:12:57
注意:此错误只出现一次。
然后很难多说,可能只是// Other Code等人花了很长时间,整个事情都被杀了。可能是你的连接中断了,或者是管理员故意因为你的阻塞而把它杀死了。
代码中的错误是什么?
使它变得过于复杂;它可以简单得多:
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using(var transaction = connection.BeginTransaction())
{
try
{
sessionID = GetSessionIDForAssociate(connection, empID, transaction);
//Other Code
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}更不用说出错的代码了。
发布于 2017-06-07 09:15:33
我使用下面的代码可以再现这个错误,我使用1000个任务执行Sql,在大约300个任务成功完成之后,大量关于timeout error的异常开始在ExecuteNonQuery()上发生,
然后,下一个错误This SqlTransaction has completed将发生在transaction.RollBack();上,其调用堆栈也包含ZombieCheck()。
(如果单个程序对1000个任务的压力不够,您可以同时执行多个已编译的exe文件,甚至可以使用多台计算机执行一个DataBase。)
因此,我猜导致此错误的原因之一可能是连接中的错误,然后导致事务错误也会发生。
Task[] tasks = new Task[1000];
for (int i = 0; i < 1000; i++)
{
int j = i;
tasks[i] = new Task(() =>
ExecuteSqlTransaction("YourConnectionString", j)
);
}
foreach (Task task in tasks)
{
task.Start();
}
/////////////
public void ExecuteSqlTransaction(string connectionString, int exeSqlCou)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
// Start a local transaction.
transaction = connection.BeginTransaction();
// Must assign both transaction object and connection
// to Command object for a pending local transaction
command.Connection = connection;
command.Transaction = transaction;
try
{
command.CommandText =
"select * from Employee";
command.ExecuteNonQuery();
// Attempt to commit the transaction.
transaction.Commit();
Console.WriteLine("Execute Sql to database."
+ exeSqlCou);
}
catch (Exception ex)
{
Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
// Attempt to roll back the transaction.
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
// This catch block will handle any errors that may have occurred
// on the server that would cause the rollback to fail, such as
// a closed connection.
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}此外,我发现如果连续提交两次,也会调用此异常。
transaction.Commit();
transaction.Commit();或者,如果连接在提交之前关闭,也会调用此错误。
connection.Close();
transaction.Commit();更新:
我觉得奇怪的是,我创建了另一个新表,并向其中插入了50万个数据,
然后在select * from newtable sql中使用100000个任务,同时运行5个程序,这一次会发生超时错误,但是当transaction.Rollback()没有调用SQLTransaction has completed error时。
但是,如果发生超时错误,跳入catch块,并且在catch块中再次执行transaction.Commit(),则会发生SQLTransaction has completed error。
https://stackoverflow.com/questions/15293673
复制相似问题