当我尝试调用包含 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
//
}
}
我在事务中创建与同一数据库的另一个连接是否有问题?
经过一些研究,似乎我无法使用 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
}
}
当我遇到这个异常时,出现了一个InnerException“事务超时”。由于这是在调试会话期间,当我在 TransactionScope 内暂停代码一段时间时,我选择忽略这个问题。
当已部署的代码中出现此特定超时异常时,我认为 .config 文件中的以下部分将帮助您:
<system.transactions>
<machineSettings maxTimeout="00:05:00" />
</system.transactions>
我也遇到了同样的问题,我将事务超时更改为 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();
...
}
当我的事务嵌套在另一个事务中时,我遇到了此错误。是否有可能存储过程声明自己的事务或者调用函数声明一个事务?
对我来说,当我在另一个事务块内遇到异常后尝试回滚事务块时,会出现此错误。
我所要做的就是删除我的内部交易块来修复它。
使用嵌套事务时,事情可能会变得非常混乱,最好避免这种情况,只需重构代码即可。
就我而言,解决方案既不是增加“transactionscope”的时间,也不是增加 machine.config 文件的“system.transactions”的“machineSettings”属性的时间。
在这种情况下,有一些奇怪的事情,因为这个错误只发生在信息量非常大的时候。
所以问题是基于这样一个事实:在事务内部的代码中,有许多“foreach”对不同的表进行更新(我不得不在其他人员开发的代码中解决这个问题)。如果测试时表中记录很少,则不会显示错误,但如果记录数增加,则会显示错误。
最终的解决方案是从单个事务更改为事务内不同“foreach”中的多个单独事务。
您不能同时打开两笔交易。我所做的是在返回第二个事务将使用的结果之前指定 transaction.Complete() ;)
我更新了一些处理部分数据库进程的专有第三方库,并在所有保存调用中收到此错误。我必须更改 web.config 事务密钥部分中的值,因为(事实证明)引用的事务范围方法已从一个库移至另一个库。
之前还有其他错误与该密钥相关,但我通过注释掉该密钥来消除它们(我知道我当时应该持怀疑态度,但我认为它现在是多余的,因为它不在闪亮的新版本中)图书馆)。
对于登陆此页面的任何人,这里有另一个可能的原因:留意异步数据库调用。
这行不通:
//pseudocode
using (new TransactionScope(whatever))
{
await QueryDatabase();
//"await" frees up the thread, it goes back into the pool
//and if other code calls the database again
//on the freed-up thread, it will fail
}