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

当尝试调用包含 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
//
}
}

在事务中创建到同一数据库的另一个连接是否存在问题?

121024 次浏览

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

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

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


}

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

当这个带有超时的特定异常出现在已部署的代码中时,我认为下面的部分。配置文件将帮助您:

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

对于我来说,这个错误出现在我试图回滚一个事务块后,遇到一个异常,在另一个事务块。

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

在使用嵌套事务时,事情可能会变得相当混乱,最好避免这种情况,只是重新构造代码。

以后遇到这种情况的流浪者。如果您的应用程序和数据库位于不同的计算机上,并且您正在收到上述错误,特别是在使用 TransactionScope 时,请启用 Network DTC 访问。这样做的步骤是:

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

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

DTC photo

在我的例子中,解决方案既不是增加“ transactionscope”的时间,也不是增加 machine.config 文件的“ system.actions”的“ machineSettings”属性的时间。

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

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

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

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

我更新了一些专有的第三方库,它们处理了数据库进程的一部分,并且在所有要保存的调用中都出现了这个错误。我必须更改 web.config 事务键部分中的一个值,因为(事实证明)引用的事务作用域方法已经从一个库转移到另一个库。

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