DbConnection.EnlistTransaction是做什么的?

13
DbConnection.EnlistTransaction是什么意思?

查看文档?http://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.enlisttransaction.aspx - Dave Hogan
1
我在那里检查过之后才来这里问。 - Stav Alfi
文档 - 如上所述 - 在“备注”下面很好地描述了它。 - Dave Hogan
10
我同意提问者的观点。这份文件很不清晰。我应该什么时候提交,什么时候关闭连接等等。我查看了MSDN,之后又查看了Stack,却只发现了你那些聪明的话和贬低评价。 - k.c.
2个回答

10

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
    如果您想在没有加入另一个事务的情况下使用连接进行其他操作,则可能需要在事务完成后保留该连接。某些连接似乎会自动退出事务,而其他连接则似乎不会。当之前的事务是分布式的时,作用域处理结束后连接的行为也可能会改变。在这种情况下,一旦所有参与者已经投票(两阶段提交的第一阶段),作用域处理便可以结束,并且在第二阶段执行并发代码,包括连接本身的第二阶段。(见此处)根据连接实现的不同,明确请求退出事务可能会缓解问题。

DbConnection.EnlistTransaction通常与System.Transactions.Transaction.Current一起使用。如果连接在TransactionScope内获得(打开),则无需使用它:在这种情况下,连接会自动加入当前事务(除非其连接字符串使用enlist=false)。但是,再次强调,某些连接实现在此处可能会有所不同:一些默认情况下未启用自动注册,对此具有完全不同的语义(例如,在其6.0版本之前的FbConnection),或使用不同的连接字符串参数(例如,MySqlConnection使用AutoEnlist)。


5

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


1
只有在事务范围内获取连接时才能保证自动注册。如果在事务范围外获取连接,然后在范围内使用,则不会自动注册。(至少我曾经看到过这样的情况,当一个连接首先在另一个事务范围下获取时:为了在第一个范围完成后与下一个范围一起使用它,需要显式地注册它。) - Frédéric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接