2010-10-21 79 views
1

我在哪里可以找到信息,或者我怎么能在一个BackgroundWorker线程处理SQL Server事务?我的理解是不应该在“DoWork”事件中设置错误处理,并且错误在内部处理并传递到“RunWorkerCompleted”。.NET的BackgroundWorker和SQLTransactions

我目前使用SubSonic作为我的DAL并传递一些冗长的插入和更新通过一个BackGroundWorder线程,我遇到的问题是,当某些事情失败时,什么都不回滚,我决定使用一个transactionscope,但是找不到使用BackgroundWorker线程处理事务的信息

+0

Rob ...你能给我一个这样的评论吗? – 2010-10-22 00:47:05

回答

1

TransactionScope的事务非常简单。

  1. 创建一个新的TransactionScope(using块内prefferable)

  2. 创建一个新的SQL连接(如果你这样做反过来想它不会工作)

  3. 运行一些CRUD操作

  4. 完成交易

  5. ???

  6. 利润!

在亚音速这个条款是你必须做的:

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 ;-)"); 
} 
+0

谢谢你的回应。我在某个地方(搜索intel)阅读过,它不建议在BackgroundWorker线程的DoWork()中使用TRY CATCH块。 – 2010-10-23 01:49:20

+1

好吧,快速谷歌搜索验证:http://social.msdn.microsoft.com/forums/en-US/Vsexpressvcs/thread/74d91404-9bc8-4f8f-8eab-4265afbcb101/的底线是。不要处理异常,但要评估RunWorkerCompleted事件中的e.Error属性。无论如何,这并不意味着您不能在DoWork()事件内部出现异常,并且使用TransactionScope您不需要捕获异常来回滚事务,因此您应该没问题。 – 2010-10-23 10:55:43