【问题标题】:Multiple TransactionScope problem多个 TransactionScope 问题
【发布时间】:2010-11-23 10:11:59
【问题描述】:

我想创建一个事务,在子事务中写入一些数据,读回数据,回滚事务。

using(var transaction = new TransactionScope()) 
{
     using(var transaction = new TransactionScope()) 
     {
          // save data via LINQ / DataContext
          transaction.Complete();
     }
     // Get back for assertions
     var tempItem = // read data via LINQ / DataContext THROWS EXCEPTION
} 

但在阅读时我得到 “System.Transactions.TransactionException : 该操作对于事务的状态无效。”。

我应该如何设置事务属性以避免这种情况?

【问题讨论】:

标签: c# .net transactions


【解决方案1】:

如果没有完整的堆栈跟踪,则无法调试此异常。根据上下文,它具有不同的含义。通常这意味着你在做一些你不应该在事务中做的事情,但是没有看到数据库调用或堆栈跟踪,任何人都可以做的就是猜测。我知道的一些常见原因(我敢肯定这绝不是全面的)包括:

  1. 在嵌套的TransactionScope 中访问多个数据源(即不同的连接字符串)。这会导致提升到分布式事务,如果您不运行 DTC,它将失败。答案通常不是启用 DTC,而是清理您的事务或使用新的 TransactionScope(TransactionOptions.RequiresNew) 包装其他数据访问。
  2. TransactionScope 中未处理的异常。
  3. 任何违反隔离级别的操作,例如尝试读取刚刚插入/更新的行。
  4. SQL 死锁;在某些情况下,事务甚至会自己死锁,但如果 #1 适用,如果您不小心,将其他操作隔离到新事务中可能会导致死锁。
  5. 事务超时。
  6. 数据库中的任何其他错误。

我绝对不知道所有可能的原因,但是如果您在代码中发布完整的堆栈跟踪和实际的 db 调用,我会看一下,如果我看到任何内容,请告诉您。

【讨论】:

  • 安迪,感谢您的回答。关于 #3 的问题:“任何违反隔离级别的操作”。以下内容会违反隔离级别吗?声明(atSmbol)someCount INT; UPDATE dbo.Something SET (atSmbol)someCount = [SomeCount] = [SomeCount]+ 1 WHERE ID = 123 在我的使用中 (atSmbol)someCount 是一个输出参数。如果是这样,这不会违反隔离级别吗?声明(atSmbol)someCount INT; UPDATE dbo.Something SET [SomeCount] = (atSmbol)someCount = [SomeCount]+ 1 WHERE ID = 123 注意,当我使用 at 符号时,它认为我试图标记某人以获取通知。
【解决方案2】:

你有两个嵌套的 TransactionScope 对象??

而且没有 try catch 块。

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

我想您会发现具体的答案是您无法完成尚未开始的交易,它处于无效状态。您实际上有任何代码在您的 LINQ cmets 所在的位置吗?真的建立了连接吗?

【讨论】:

  • 是的,嵌套的。但是为什么要链接 MSDN?
  • 因为链接的文章解释了为什么您会收到该异常,也许?
  • @boj:因为它有一个很好的 cmets 的用法示例,解释了发生的事情和时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多