TransactionScope的事务非常简单。
创建一个新的TransactionScope(using块内prefferable)
创建一个新的SQL连接(如果你这样做反过来想它不会工作)
运行一些CRUD操作
完成交易
???
利润!
在亚音速这个条款是你必须做的:
using (var ts = new TransactionScope())
using (new SubSonic.SharedDbConnectionScope())
{
DoSomethingWithYourData();
ts.Complete();
}
这是在后台发生了什么:
如果您创建一个新的TransactionScope,静态产权交易。当前设置为您的交易。现在,如果您创建一个新的DbConnection,连接itselfs看起来如果Transaction.Current不是null suscribes到TransactionCompleted事件。
如果调用ts.Complete()的连接设置之前,该交易将提交否则将被回滚在TransactionScopes Dispose()方法的一个例外是抛出。
亚音速本身会为你创建执行每个语句的新的连接(没有错误,这是由德兴),但不实际的交易。这就是SharedDbConnectionScope()存在的原因。它的工作方式类似于TransactionScope(如果新的AutomaticConnectionScope检测到存在当前的SharedDbConnectionScope(),则将使用它的连接。否则将创建新的连接。 :
var obj = new ObjectThatImplementsIDisposable();
try
{
}
finally
{
obj.Dispose();
}
长话短说:如果你在一个线程或BackgroundWorker的运行它,它不会影响你的交易但是,你应该记住的是,如果你使用一个SharedDbConnecionScope()甚至从其他线程的查询会。使用它们我不认为SqlClient库是线程安全的(但我可能是错的,但MySqlClient肯定不是。
Conculstion:我会切换到TransactionScope的,因为它使用方便,灵活,通用的(如果你决定有一天切换到MySQL或Oracle与您的应用程序,您不必担心)
读你这个问题的第一部分: - 我认为让BackGroundWorker的DoWork方法抛出异常是一个不好的想法。但你可以使用这种方法:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
ExecuteATransaction()
}
catch (Exception ex)
{
RollBackTransaction();
e.Result = ex;
}
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result && e.Result.GetType() == typeof(Exception))
throw ((Exception)e.Result);
else
Console.WriteLine("Everything went better than expected ;-)");
}
Rob ...你能给我一个这样的评论吗? – 2010-10-22 00:47:05