使用事务执行 SqlCommand 时出现 InvalidOperationException

发布于 2024-07-11 10:26:59 字数 999 浏览 8 评论 0原文

我有这段代码,在两个单独的线程中并行运行。 有几次它工作正常,但在某个随机点它会抛出 InvalidOperationException:

事务要么与当前连接不关联,要么已完成。

在异常情况下,我正在使用 Visual Studio 查看事务内部并验证其连接是否设置正常。 还有command.Transaction._internalTransaction。 _transactionState 设置为 Active,IsZombied 属性设置为 false。

这是一个测试应用程序,我使用 Thread.Sleep 来创建更长的事务并导致重叠。

为什么会抛出异常以及我该怎么办?

IDbCommand command = new SqlCommand("Select * From INFO");
IDbConnection connection = new SqlConnection(connectionString);
command.Connection = connection;
IDbTransaction transaction = null;
try
{
    connection.Open();
    transaction = connection.BeginTransaction();
    command.Transaction = transaction;
    command.ExecuteNonQuery(); // Sometimes throws exception
    Thread.Sleep(forawhile); // For overlapping transactions running in parallel
    transaction.Commit();
}
catch (ApplicationException exception)
{
    if (transaction != null)
    {
        transaction.Rollback();
    }
}
finally
{
    connection.Close();
}

I have this code, running parallel in two separate threads. It works fine for a few times, but at some random point it throws InvalidOperationException:

The transaction is either not associated with the current connection or has been completed.

At the point of exception, I am looking inside the transaction with visual studio and verify its connection is set normally. Also command.Transaction._internalTransaction. _transactionState is set to Active and IsZombied property is set to false.

This is a test application and I am using Thread.Sleep for creating longer transactions and causing overlaps.

Why may the exception being thrown and what can I do about it?

IDbCommand command = new SqlCommand("Select * From INFO");
IDbConnection connection = new SqlConnection(connectionString);
command.Connection = connection;
IDbTransaction transaction = null;
try
{
    connection.Open();
    transaction = connection.BeginTransaction();
    command.Transaction = transaction;
    command.ExecuteNonQuery(); // Sometimes throws exception
    Thread.Sleep(forawhile); // For overlapping transactions running in parallel
    transaction.Commit();
}
catch (ApplicationException exception)
{
    if (transaction != null)
    {
        transaction.Rollback();
    }
}
finally
{
    connection.Close();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

这个俗人 2024-07-18 10:26:59

找到了解决方案。 事实证明,调用此方法

command.Connection = connection;

并不意味着您设置了与该命令的连接。 调用此函数后,我检查了结果

command.Connection.GetHashCode();
command.GetHashCode();

,发现它们不相等。 重构代码以使用connection.CreateCommand,问题得到解决。

Found the solution. Turns out calling this

command.Connection = connection;

does not mean that you set the connection to the command. Just after calling this, I checked the results of

command.Connection.GetHashCode();
command.GetHashCode();

and they were not equal. Refacotored the code to use connection.CreateCommand and the problem solved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文