【问题标题】:How to manage transactions in the service layer?如何在服务层管理事务?
【发布时间】:2011-02-01 19:24:26
【问题描述】:

我们正在开发一个具有以下架构的 .Net 应用程序:表示层(使用带有 ASP.Net MVC 2 的 MVC 模式)、服务层、数据访问层(使用实体框架上的存储库模式)。

我们决定将事务管理放在服务层,但我们不确定如何实现它。我们希望完全在服务层级别控制事务。也就是说,每次控制器调用服务层中的方法时,都必须是关于数据库更新的原子操作。

如果服务层提供的不同服务之间没有关系,那么它会很简单:每个方法都应该在其执行结束时提交更改(即,在它使用的上下文中调用 save 方法)。但有时服务层的服务会协同工作。

例如:我们提供的发货服务有一个确认方法,该方法接收以下参数:发货 id,指示它对应于新客户还是现有客户的标志,客户 ID(如果发货确认是现有客户)和客户名称(如果是新客户)。如果标志设置为“新客户”,则服务层必须 (a) 创建客户并 (b) 确认发货。对于 (a) 发货服务调用客户服务(它已经实现了创建新客户并将其存储在数据库中所需的验证和逻辑)。

谁应该在这种情况下提交更改?

  • 客服应该做吗?创建新客户后它无法提交更改,因为稍后在发货确认方法中可能会出错,但它必须在直接调用的情况下提交更改(在其他用例中,提供用于创建客户端)。
  • 调用服务方法的控制器应该这样做吗?但是控制器不应该知道任何关于事务的知识,我们决定将所有事务知识都放在服务层中。
  • 服务层中的事务管理器?如何设计它?谁叫它,什么时候叫它?

是否有我们应该遵循的设计模式?

【问题讨论】:

    标签: asp.net-mvc entity-framework transactions service-layer


    【解决方案1】:

    我的服务上有一个 Commit(),只有在服务创建 UnitOfWork 时才会提交,如果它在构造函数中传递,则提交什么也不做。

    我为服务使用了第二个(内部)构造函数:

    public class MyService
    {
    private IUnitOfWork _uow;
    private bool _uowInternal;
    
    public MyService()
    {
        _uow = new UnitOfWork();
        _uowInternal = false;
    }
    
    internal MyService(IUnitOfWork uow)
    {
        _uow = uow;
        _uowInternal = true;
    }
    public MyServiceCall()
    {
        // Create second service, passing in my UnitOfWork:
        var svc2 = new MySecondService(_uow);
    
        // Do your stuff with both services.
        ....
        // Commit my UnitOfWork, which will include all changes from svc2:
        Commit();
    }
    
    public void Commit()
    {
        if(!_uowInternal)
            _uow.Commit();
    }
    }
    

    【讨论】:

    • 谢谢约翰!正是我正在寻找的那种答案。
    【解决方案2】:

    在使用 WCF 和 L2S 而不是 EF 的类似架构中,我们选择在主服务接口实现类中使用事务。我们使用TransactionScope 来实现这一点:

    public void AServiceMethod() {
        using(TransactionScope ts = new TransactionScope()) {
             service1.DoSomething();
             service2.DoSomething();
             ts.Complete();
        }
    }
    

    主要缺点是交易可能会变大。在这种情况下,如果事务块中的一个服务调用只需要只读访问,我们将其包装在嵌套的 TransactionScope(TransactionScopeOption.Suppress) 块中,以防止在事务生命周期中进一步锁定行/表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      相关资源
      最近更新 更多