user366312
user366312

Reputation: 17012

BeginTran(), Commit() and Rollback() in Repository Pattern

While creating a repository by using NHibetnate(or, whatever), should I keep explicit BeginTransaction(), Commit(), Rollback() like the following?

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();
    }
}

Or, should I write my persistence methods like this?

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;
            }            
        }

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

Any suggestion? Can anyone compare these two approaches?

Upvotes: 1

Views: 2169

Answers (2)

Jamie Ide
Jamie Ide

Reputation: 49291

My approach is to let the UI/whatever control the scope of a unit of work (ISession) and pass the ISession into repository constructors as a dependency. That way a single unit of work can enlist as many repositories as needed in a transaction.

Upvotes: 1

Anton Gogolev
Anton Gogolev

Reputation: 115859

Create a separate ITransactionManager, which will return My.ITransaction which you'll later commit and rollback as needed.

Currently you're just pollutin class interface and introducing complexity and weirdness (for instance, can I call BeginTransation in one repository and then Commit it in another?).

Upvotes: 2

Related Questions