2011-09-24 48 views
3

我有一个用户存储库,它执行所有用户数据访问。我还有一个工作单位班级,负责管理我的存储库的连接和事务。如果在我的存储库中发生错误,我如何有效回滚工作单元类中的事务?如何使用Unit of Work和Repository模式回滚事务?

在我的UserRepository上创建方法。我正在使用Dapper进行DataAccess。

try 
{ 
    this.Connection.Execute("User_Create", parameters, this.Transaction, 
     commandType: CommandType.StoredProcedure); 
} 
catch (Exception) 
{ 
    //Need to tell my unit of work to rollback the transaction.     
} 

我将在我的工作单元构造函数中创建的连接和事务都传递给我的存储库。下面是我的工作单元班的一个属性。

public UserRepository UserRepository 
{ 
    get 
    { 
     if (this._userRepository == null) 
      this._userRepository = 
       new UserRepository(this._connection, this._transaction); 
     return this._userRepository; 
    } 
} 

我希望找出最好的方法。

*更新* 做更多的研究工作模式的单位,我认为我使用它在我的例子完全错误之后。

回答

5

Dapper支持TransactionScope,它提供了一个Complete()方法来提交事务,如果您不呼叫Complete()事务被中止。

using (TransactionScope scope = new TransactionScope()) 
{ 
    //open connection, do your thing 
    scope.Complete(); 
} 
+1

如果这是.net框架的TransactionScope它不是正确的解决方案。 SqlTransaction是正确的方式,因为它更轻量级。除非有使用TransactionScope的令人信服的理由(我没有看到),我不会建议使用 – thekip

+1

@thekip:没有“正确”或“错误”解决方案;对于你来说,轻量级可能意味着它是适合你*需求的解决方案。但是,['TransactionScope'](http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscope.aspx)通过适当分离关注点解决了多对象问题,这些问题更多的是(否则,您必须通过['SqlTransaction'](http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqltransaction.aspx))通过所有的涉及交易的层和对象,不是很干净)。 – casperOne

+1

必须通过图层传递交易是一个设计缺陷。如果你正确地执行一个工作单元,那么当你想执行这个工作单元时,你只需要开始一个事务。如果将工作单元的执行与添加要执行的所有操作(即问题出在哪里)的关注混合在一起。 – thekip