存储库模式中的BeginTran(),Commit()和Rollback()

时间:2010-01-20 14:28:54

标签: c# repository design-patterns

在使用NHibetnate(或者其他)创建存储库时,我应该保持显式的BeginTransaction(),Commit(),Rollback(),如下所示吗?

public class NHibernateRepository<T> : IRepository<T>
{
    private NHibernate.ISession _session;

    public NHibernateRepository()
    {
        _session = NHibernateSessionManager.Instance.GetSession();
        _session.BeginTransaction();
    }

    public void Save(T obj)
    {
        _session.Save(obj);
    }

    ... ... ... ... ... ... ...

    public void Commit()
    {
        if (_session.Transaction.IsActive)
        {
            _session.Transaction.Commit();
        }
    }

    public void Rollback()
    {
        if (_session.Transaction.IsActive)
        {
            _session.Transaction.Rollback();
            _session.Clear();
        }
    }

    public void BeginTransaction()
    {
        Rollback();
        _session.BeginTransaction();
    }
}

或者,我应该写这样的持久性方法吗?

public class Repository<T> : IRepository<T>
    {
        ISession _session;

        public Repository()
        {
            _session = SessionFactoryManager.SessionFactory.OpenSession();
        }

        private void Commit()
        {
            if (_session.Transaction.IsActive)
            {
                _session.Transaction.Commit();
            }
        }

        private void Rollback()
        {
            if (_session.Transaction.IsActive)
            {
                _session.Transaction.Rollback();
                _session.Clear();
            }
        }

        private void BeginTransaction()
        {
            _session.BeginTransaction();
        }

        void IRepository<T>.Save(T obj)
        {
            try
            {
                this.BeginTransaction();

                _session.Save(obj);                

                this.Commit();
            }
            catch (Exception ex)
            {
                this.Rollback();

                throw ex;
            }            
        }

        ... ... ... ... ... ... ...
    }
}

有什么建议吗?谁能比较这两种方法呢?

2 个答案:

答案 0 :(得分:2)

创建一个单独的ITransactionManager,它将返回My.ITransaction,您将在以后提交并根据需要进行回滚。

目前,您只是污染类接口并引入复杂性和怪异性(例如,我可以在一个存储库中调用BeginTransation,然后在另一个存储库中调用Commit吗?)。

答案 1 :(得分:1)

我的方法是让UI /无论控制工作单元(ISession)的范围,并将ISession作为依赖项传递给存储库构造函数。这样,单个工作单元就可以在事务中根据需要获得尽可能多的存储库。