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();
}
}
pr开发者_JAVA技巧ivate 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?
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?).
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.
精彩评论