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

时间:2008-10-10 21:49:52

标签: c# .net 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
        //
    }
}

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

8 个答案:

答案 0 :(得分:48)

在做了一些研究之后,我似乎无法使用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
    }
}

答案 1 :(得分:9)

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

}

答案 2 :(得分:7)

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

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

<system.transactions> 
        <machineSettings maxTimeout="00:05:00" /> 
</system.transactions>

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

我必须做的就是删除我的内部事务块。

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

答案 5 :(得分:1)

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

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

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

DTC photo

答案 6 :(得分:0)

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

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

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

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

答案 7 :(得分:0)

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