存储库服务是否知道事务信息



我将NHibernate与存储库设计模式结合使用。在当前任务中,我需要在同一事务中更新一个实体并删除另一个实体。我想在Repository's Services层声明ISession.BeginTransaction(),并将其传递给Repository's method,如下所示:

public class SomeEntity
{
    //entity's properties
}
public class EntityRepository : IEntityRepository
{
    public void update(ISession session, Entity entity)
    {
        session.Update(entity);
    }
    public void delete(ISession session, Entity entity)
    {
        session.Delete(entity);
    }
}
public class EntityService
{
    private IEntityRepository repository;
    public EntityService(IEntityRepository repository)
    {
        //I'm using Ninject for DI here
        this.repository = repository;
    }
    public void DoTask(Entity _updateEntity, Entity _deleteEntity)
    { 
        ISession session = NHibernateHelper.OpenSession();
        using(ITransaction transaction = session.BeginTransaction())
        {
            this.repositoy.update(session, _updateEntity);
            this.repositoy.delete(session, _deleteEntity);
            transaction.Commit();
        }
    }
}

我想问的是

  1. Repository's Service layer管理ISession以及ITransaction并将其传递给Associate Repository是一个好主意吗?
  2. 如果这不是一个好主意,我应该如何改变我的设计,以便在同一个事务中执行这些任务,而不让Repository's Service layer知道该事务,但仍然使Repository layer尽可能轻量级?

编辑

为了澄清,我的EntityService是一个business logic layer,它依赖于Repository来执行business logic,然后将结果传递给presentation layer(在我的情况下是一个winform)。所以我认为让EntityService管理ISessionITransaction会导致tight coupling,这是我首先要避免的。

编辑2

根据ptk93,我做了一些改变,设计如下:

public class SomeEntity
{
    //entity's properties
}
public class EntityRepository : IEntityRepository
{
    private ISession session;
    private ITrasaction trasaction;
    public EntityRepository()
    {
        this.session = NHibernateHelper.OpenSession();
    }
    public void BeginTransaction()
    {
        if(this.transaction != null && this.transaciont.isActive)
        {
            throw new Exception();
        }
        this.transaction = this.session.BeginTransaction();
    }
    public void CommitTransaction()
    {
        if(this.transaction == null || this.transaction.isActive = false)
        {
            throw new Exception();
        }
        this.transaction.Commit();
        this.transaction.Dispose();
    }
    public void update(ISession session, Entity entity)
    {
        if(this.transaction == null || this.transaction.isActive = false)
        {
            throw new Exception();
        }
        session.Update(entity);
    }
    public void delete(ISession session, Entity entity)
    {
        if(this.transaction == null || this.transaction.isActive = false)
        {
            throw new Exception();
        }
        session.Delete(entity);
    }
}
public class EntityService
{
    private IEntityRepository repository;
    public EntityService(IEntityRepository repository)
    {
        //I'm using Ninject for DI here
        this.repository = repository;
    }
    public void DoTask(Entity _updateEntity, Entity _deleteEntity)
    { 
        this.repository.BeginTransaction()
        this.repositoy.update(session, _updateEntity);
        this.repositoy.delete(session, _deleteEntity);
        this.repository.CommitTransaction();            
    }
}

这个设计是否足以解耦RepositoryRepository Service ?

你可以在边界和控制服务中分离你的服务。边界对客户端、网页等是可见的,而控件只对边界服务可见。您的存储库对客户端可见吗?在您的用例中,似乎存储库仅由其他服务而不是客户端本身使用,因此它们是控件。控件应该被标记为MANDATORY,这样如果在没有启动事务的情况下调用控件,并且在您的边界中从方法的开始到结束必须启动事务,那么它们将抛出异常。

在这种情况下,您正在使用控件/存储库UserRepository和AddressRepository创建具有三个地址的用户,它们都将在同一事务中开始于边界RegistrationService的register方法的开始。
如果要删除所有联系信息,AddressRepository和MailRepository控件必须在另一个名为ContactService的边界内使用,该边界具有不同的事务边界。

这样的决定取决于您的用例,但在我看来,实体-控制-边界模式可以满足您的需求。

我个人更喜欢在服务中具有事务控制,因为有时您希望在同一事务中访问多个存储库,否则存储库可能会抛出异常,无法回滚与前一个事务相关的更改。

已经说过,我们在库库库中也有帮助器来管理事务,以便在您只更新一个库的情况下更容易使用库。

相关内容

  • 没有找到相关文章

最新更新