首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SqlTransaction已完成

SqlTransaction已完成
EN

Stack Overflow用户
提问于 2009-03-04 17:51:26
回答 9查看 32.8K关注 0票数 25

我有一个可能对SQL Server2005数据库执行数千次插入的应用程序。如果由于任何原因(外键约束、字段长度等)而导致插入失败该应用程序旨在记录插入错误并继续。

每个插入操作都独立于其他插入操作,因此数据库完整性不需要事务处理。但是,我们确实希望使用它们来提高性能。当我使用事务时,我们每100次提交中就会有1次出现以下错误。

代码语言:javascript
复制
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)。然而,他们提供的修复程序并没有解决这个问题。

EN

回答 9

Stack Overflow用户

发布于 2009-03-05 22:00:50

感谢所有的反馈。我一直在MSDN论坛上与来自MSFT的人合作,以弄清楚发生了什么。事实证明,这个问题是由于日期时间转换问题导致其中一个插入失败造成的。

主要问题是,如果是日期转换错误,则会显示此错误。但是,如果是另一个错误,如字段太长,则不会导致此问题。在这两种情况下,我都希望事务仍然存在,所以我可以对它调用Rollback。

我有一个完整的示例程序来复制这个问题。如果任何人希望看到它或与微软的交流,你可以在微软新闻组的SqlTransaction.ZombieCheck错误线程下的microsoft.public.dotnet.framework.adonet中找到该线程。

票数 11
EN

Stack Overflow用户

发布于 2009-03-04 19:07:11

在看不到代码的情况下很难提供帮助。根据您的描述,我假设您正在使用事务在每N次插入之后提交一次,如果N不太大,这将比每次提交一次插入提高性能。

但缺点是:如果插入失败,则在回滚事务时,当前批N内的任何其他插入都将被回滚。

通常,您应该在关闭连接之前处理事务(如果事务尚未提交,则会回滚该事务)。通常的模式如下所示:

代码语言:javascript
复制
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

如果您需要更多帮助,请发布代码。

票数 7
EN

Stack Overflow用户

发布于 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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/611700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档