79

当我尝试调用包含 SELECT 语句的存储过程时出现以下错误:

该操作对事务的状态无效

这是我的通话结构:

public void MyAddUpdateMethod()
{

    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement

            //do my call to the select statement sp
            bool DoesRecordExist = this.SelectStatementCall(id)
        }
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring)) //breaks on this line
    {
        //create parameters
        //
    }
}

我在事务中创建到同一个数据库的另一个连接有问题吗?

4

9 回答 9

66

在做了一些研究之后,似乎我无法使用 TransactionScope 块打开两个连接到同一个数据库。我需要修改我的代码看起来像这样:

public void MyAddUpdateMethod()
{
    using (TransactionScope Scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        using(SQLServer Sql = new SQLServer(this.m_connstring))
        {
            //do my first add update statement            
        }

        //removed the method call from the first sql server using statement
        bool DoesRecordExist = this.SelectStatementCall(id)
    }
}

public bool SelectStatementCall(System.Guid id)
{
    using(SQLServer Sql = new SQLServer(this.m_connstring))
    {
        //create parameters
    }
}
于 2008-10-15T01:07:19.267 回答
16

当我遇到这个异常时,有一个 InnerException "Transaction Timeout"。由于这是在调试会话期间,当我在 TransactionScope 内暂停我的代码一段时间时,我选择忽略这个问题。

当已部署的代码中出现此特定的超时异常时,我认为 .config 文件中的以下部分将为您提供帮助:

<system.transactions> 
        <machineSettings maxTimeout="00:05:00" /> 
</system.transactions>
于 2012-02-06T13:26:45.840 回答
13

我也遇到了同样的问题,我将事务超时更改为 15 分钟,它可以工作。我希望这有帮助。

TransactionOptions options = new TransactionOptions();
options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
options.Timeout = new TimeSpan(0, 15, 0);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options))
{
    sp1();
    sp2();
    ...

}
于 2010-11-30T11:36:21.353 回答
5

当我的事务嵌套在另一个事务中时,我遇到了这个错误。存储过程是否有可能声明自己的事务或调用函数声明一个?

于 2008-10-10T21:55:00.607 回答
5

对于将来遇到这种情况的任何流浪者。如果您的应用程序和数据库位于不同的机器上,并且您遇到上述错误,尤其是在使用 TransactionScope 时,请启用网络 DTC 访问。执行此操作的步骤是:

  1. 添加防火墙规则以允许您的机器相互通信。
  2. 确保分布式事务协调器服务正在运行
  3. 启用网络 dtc 访问。运行 dcomcnfg。转到组件服务 > 我的电脑 > 分布式事务协调器 > 本地 DTC。右键单击属性。
  4. 如图所示启用网络 dtc 访问。

重要提示:不要编辑/更改 DTC 登录帐户字段中的用户帐户和密码,保持原样,如果这样做,您最终将重新安装 Windows。

故障诊断卡照片

于 2020-08-19T11:33:44.073 回答
2

对我来说,当我在另一个事务块内遇到异常后尝试回滚事务块时出现了这个错误。

我所要做的就是删除我的内部事务块。

使用嵌套事务时事情可能会变得非常混乱,最好避免这种情况并重新构建代码。

于 2018-05-04T14:10:04.217 回答
1

就我而言,解决方案既不是增加“transactionscope”的时间,也不是增加 machine.config 文件的“system.transactions”的“machineSettings”属性的时间。

在这种情况下,有一些奇怪的事情,因为这个错误只发生在信息量非常大的时候。

所以问题是基于这样一个事实,即在事务内部的代码中有许多“foreach”对不同的表进行更新(我必须在其他人员开发的代码中解决这个问题)。如果在表中的记录很少的情况下执行测试,则不会显示错误,但如果记录数增加,则会显示错误。

最后,解决方案是将单个事务更改为事务内不同“foreach”中的几个单独事务。

于 2021-06-03T21:48:14.457 回答
0

您不能同时打开两个事务。我所做的是在返回将由第二个事务使用的结果之前指定transaction.Complete() ;)

于 2021-08-10T08:08:44.687 回答
0

我更新了一些处理部分数据库进程的专有第 3 方库,并在所有调用保存时都出现此错误。我不得不更改 web.config 事务键部分中的值,因为(事实证明)引用的事务范围方法已从一个库移动到另一个库。

以前还有其他与该密钥相关的错误,但我通过注释掉密钥来消除它们(我知道我当时应该怀疑,但我认为它现在是多余的,因为它不在闪亮的新库中)。

于 2021-11-15T14:27:57.767 回答