Ian*_*oyd 6 .net transactionscope
我如何加入正在进行的TransactionScope?
如果您使用TransactionScope,您可以创建一个“环境”事务:
using (TransactionScope scope = new TransactionScope())
{
//...stuff happens, then you complete...
// The Complete method commits the transaction.
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
那有什么用呢?好吧,.NET 框架中有一些类知道如何通过检查以下内容来检查是否存在环境正在进行的事务static
:
这让他们知道有一项交易正在进行中。
例如,如果您有一些不考虑事务的任意数据库操作:
void DropStudents()
{
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "DROP TABLE Students;";
cmd.ExecuteNonQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
如果你把它放在TransactionScope的中间:
using (TransactionScope scope = new TransactionScope())
{
DropStudents();
// The Complete method commits the transaction.
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
突然间,您的 ADO.net 操作处于事务中;并且可以回滚。
SqlClient库知道要检查:
并自动在内部:
这一切都只是魔法。
DbConnection
收到了打电话的通知.Commit
DbConnection
收到通知.Rollback
我有一堂课也有交易。而不是强迫调用者调用:
using (IContosoTransaction tx = turboEncabulator.BeginTransaction())
{
try
{
turboEncabulator.UpendCardinalGrammeters();
}
catch (Exception ex)
{
tx.Rollback();
throw;
}
tx.Commit();
}
Run Code Online (Sandbox Code Playgroud)
如果他们能直接打电话就更好了:
turboEncabulator.UpendCardinalGrammeters();
Run Code Online (Sandbox Code Playgroud)
我的代码将简单地检查:
如果有交易正在进行中,我将:
但我该怎么做呢?
我如何向正在进行的TransactionScope注册以获取这些通知?
其实没那么糟糕。
通过查看是否已分配来检查是否有正在进行的事务System.Transactions.Transaction.Current
。如果有,则Enlist
在交易中:
//Enlist in any current transactionScope if one is active
if (System.Transactions.Transaction.Current != null)
System.Transactions.Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None);
Run Code Online (Sandbox Code Playgroud)
我传递this
, 作为将通过它必须实现的接口获取通知回调的对象IEnlistmentNotification
。
然后你需要实现以下四种通知方法IEnlistmentNotification
:
void Prepare(PreparingEnlistment preparingEnlistment);
void Commit(Enlistment enlistment);
void InDoubt(Enlistment enlistment);
void Rollback(Enlistment enlistment);
实际的实现是简单的样板通知:
preparingEnlistment.Prepared();
preparingEnlistment.ForceRollback();
enlistment.Done();
enlistment.Done();
enlistment.Done();
public void Prepare(PreparingEnlistment preparingEnlistment)
{
//The transaction manager is asking for our vote if the transaction
//can be committed
//Vote "yes" by calling .Prepared:
preparingenlistment.Prepared();
//Vote "no" by calling .ForceRollback:
//preparingEnlistment.ForceRollback();
}
public void Commit(Enlistment enlistment)
{
//The transaction is being committed - do whatever it is we do to commit.
//Let them know we're done with the enlistment.
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
//Do any work necessary when indoubt notification is received.
//This method is called if the transaction manager loses contact with one or more participants,
//so their status is unknown.
//If this occurs, you should log this fact so that you can investigate later whether any of the
//transaction participants has been left in an inconsistent state.
//Let them know we're done with the enlistment.
enlistment.Done();
}
public void Rollback(Enlistment enlistment)
{
//If any resource manager reported a failure to prepare in phase 1, the transaction manager invokes
//the Rollback method for each resource manager and indicates to the application the failure of the commit.
//Let them know we're done with the enlistment.
enlistment.Done();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
854 次 |
最近记录: |