DbConnection.EnlistTransaction有什么作用?

时间:2012-10-12 17:10:19

标签: c# entity-framework transactions

DbConnection.EnlistTransaction做什么?

2 个答案:

答案 0 :(得分:5)

DbConnection.EnlistTransaction允许:

  • 加入System.Transactions.Transaction的连接。它有一些限制:
    • 如果连接已经参与“本地”事务(System.Data.Common.DbTransaction),则可能会因异常而失败。 (这似乎取决于具体的连接实现:Firebird 2在这种情况下不会抛出异常,SqlConnection并且可能大多数其他人抛出异常。)
    • 如果连接已加入另一个System.Transactions.Transaction,并且此其他事务仍处于活动状态,则会因例外而失败。
    • 支持重复加入同一交易,至少是SqlConnectionOleDbConnectionOdbcConnection。 如果连接当前正在使用某些资源,例如被打开的数据读取器使用,则可能会失败。 (这种情况看起来像对这些连接的内部实现的过早检查,在实现已提供的交易已经加入之前完成。)
      其他DbConnection实现可能有所不同。例如,HanaConnection(从HANA 2 SP3开始)会抛出这种情况,这对于在连接字符串中未禁用连接自动登记时始终显式登记的代码非常不方便。
  • 如果交易不再有效,则保留已加入连接的交易。 (否则,尝试使用连接可能会失败,但至少有OdbcConnection个例外。)提供null作为此事务的交易。
    请注意,某些连接不支持这种情况,例如SqlCeConnection会引发NullReferenceException,而SQLiteConnection(至少会引发v1.0.105)会引发ArgumentNullException
    如果您希望将连接用于某些其他操作而不在另一个事务中加入,则可能需要在事务完成后退出事务。有些连接似乎是自动离开交易,有些则似乎没有。
    范围处理后的连接行为也可能会发生变化,具体取决于先前的事务是否已分发。分发时,范围处理可以在所有参与者投票后立即结束(两阶段提交的第一阶段),使范围处理后的代码同时执行到第二阶段,同时包含在连接的第二阶段中。 (See here。)根据连接实现,明确要求退出交易可以减轻麻烦。

DbConnection.EnlistTransaction通常与System.Transactions.Transaction.Current一起使用。如果在TransactionScope内获取(打开)连接,则不需要使用它:在这种情况下,连接会自动在当前事务中登记自己(除非其连接字符串另外用enlist=false指示) 。但是再一次,一些连接实现也可能在这里有所不同:有些连接默认情况下没有启用自动登记,并且它具有完全不同的语义(如6.0版本之前的FbConnection),或者使用不同的连接字符串参数(例如MySqlConnection使用AutoEnlist)。

答案 1 :(得分:3)

它允许您协调多个连接之间的事务。如果使用TransactionScope,连接将自动登记在事务中。否则,您必须使用现有事务进行登记。