13

DbConnection.EnlistTransaction 做什么?

4

2 回答 2

10

DbConnection.EnlistTransaction允许:

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

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

于 2017-05-16T09:48:18.463 回答
5

It allows you to coordinate transactions between multiple connections. A connection will automatically enlist in a transaction if you use TransactionScope. Otherwise you have to do the enlist with an existing transaction.

于 2012-10-12T17:15:13.607 回答