"操作对事务状态无效"错误和事务范围

Mic*_*ern 59 .net c# sql-server transactions transactionscope

当我尝试调用包含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
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

我在问题中创建了另一个与同一数据库的连接的问题吗?

Mic*_*ern 53

在做了一些研究之后,我似乎无法通过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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你有一个写入数据库的日志框架(nlog,log4net),那么看到这种情况很常见,因为日志框架将创建自己的数据库连接作为你的应用程序. (4认同)
  • 记录应用程序*应该*可能会抑制任何外部TransactionScope上下文. (2认同)

Sha*_*que 11

我也遇到了同样的问题,我将事务超时更改为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();
    ...

}
Run Code Online (Sandbox Code Playgroud)

  • 我强烈怀疑,不是超时改变了行为,而是你将隔离级别从Serializable更改为ReadCommitted. (13认同)

R. *_*urs 9

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

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

<system.transactions> 
        <machineSettings maxTimeout="00:05:00" /> 
</system.transactions>
Run Code Online (Sandbox Code Playgroud)


Joh*_* K. 8

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

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

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

故障码照片


Wya*_*att 5

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


小智 5

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

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

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

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