我有一个可能对SQL Server2005数据库执行数千次插入的应用程序。如果由于任何原因(外键约束、字段长度等)而导致插入失败该应用程序旨在记录插入错误并继续。
每个插入操作都独立于其他插入操作,因此数据库完整性不需要事务处理。但是,我们确实希望使用它们来提高性能。当我使用事务时,我们每100次提交中就会有1次出现以下错误。
This SqlTransaction has completed; it is no longer usable.
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Commit()为了试图追踪原因,我在每个事务操作中都放置了跟踪语句,以便在调用commit之前确保事务不会被关闭。我已确认我的应用程序不会关闭事务。然后,我使用完全相同的输入数据再次运行应用程序,它成功了。
如果我关闭登录,它将再次失败。重新打开它,它就会成功。这种开/关切换是通过app.config完成的,不需要重新编译。
显然,日志记录的行为改变了计时并使其工作。这将指示线程问题。然而,我的应用程序不是多线程的。
我见过一个MS KB条目,指出.Net 2.0框架的错误可能会导致类似的问题(http://support.microsoft.com/kb/912732)。然而,他们提供的修复程序并没有解决这个问题。
发布于 2009-03-05 22:00:50
感谢所有的反馈。我一直在MSDN论坛上与来自MSFT的人合作,以弄清楚发生了什么。事实证明,这个问题是由于日期时间转换问题导致其中一个插入失败造成的。
主要问题是,如果是日期转换错误,则会显示此错误。但是,如果是另一个错误,如字段太长,则不会导致此问题。在这两种情况下,我都希望事务仍然存在,所以我可以对它调用Rollback。
我有一个完整的示例程序来复制这个问题。如果任何人希望看到它或与微软的交流,你可以在微软新闻组的SqlTransaction.ZombieCheck错误线程下的microsoft.public.dotnet.framework.adonet中找到该线程。
发布于 2009-03-04 19:07:11
在看不到代码的情况下很难提供帮助。根据您的描述,我假设您正在使用事务在每N次插入之后提交一次,如果N不太大,这将比每次提交一次插入提高性能。
但缺点是:如果插入失败,则在回滚事务时,当前批N内的任何其他插入都将被回滚。
通常,您应该在关闭连接之前处理事务(如果事务尚未提交,则会回滚该事务)。通常的模式如下所示:
using(SqlConnection connection = ...)
{
connection.Open();
using(SqlTransaction transaction = connection.BeginTransaction())
{
... do stuff ...
transaction.Commit(); // commit if all is successful
} // transaction.Dispose will be called here and will rollback if not committed
} // connection.Dispose called here如果您需要更多帮助,请发布代码。
发布于 2009-03-05 00:24:07
请记住,您的应用程序并不是事务的唯一参与者- SQL Server也参与其中。
你引用的错误:
此SqlTransaction已完成;它不再可用。at System.Data.SqlClient.SqlTransaction.ZombieCheck() at System.Data.SqlClient.SqlTransaction.Commit()
并不表示事务已完成,而只是表示事务已完成。
我的第一个建议是,您的服务器已经终止了事务,因为它要么花费了太长时间(ellapsed wall time),要么变得太大(太多更改或太多锁)。
我的第二个建议是检查您是否适当地清理了连接和事务。您可能会遇到问题,因为在资源被自动回收之前,您偶尔会耗尽一些资源池。
例如,DbConnection实现了IDisposable,因此您需要确保适当地进行清理-如果可以,使用using语句,或者如果不能,则直接调用Dispose()。'DbCommand'也类似,因为它也实现了IDisposable。
https://stackoverflow.com/questions/611700
复制相似问题