Fixing migration isolation and sessions lifetime

This commit is contained in:
Sebastien Ros
2014-09-15 17:28:14 -07:00
parent 0e1c0c567e
commit 85159d8728
2 changed files with 23 additions and 70 deletions
@@ -90,6 +90,8 @@ namespace Orchard.Data.Migration {
// apply update methods to each migration class for the module // apply update methods to each migration class for the module
foreach (var migration in migrations) { foreach (var migration in migrations) {
_transactionManager.RequireNew();
// copy the object for the Linq query // copy the object for the Linq query
var tempMigration = migration; var tempMigration = migration;
@@ -102,8 +104,6 @@ namespace Orchard.Data.Migration {
} }
try { try {
_transactionManager.RequireNew();
// do we need to call Create() ? // do we need to call Create() ?
if (current == 0) { if (current == 0) {
// try to resolve a Create method // try to resolve a Create method
+21 -68
View File
@@ -15,8 +15,6 @@ namespace Orchard.Data {
private readonly ISessionFactoryHolder _sessionFactoryHolder; private readonly ISessionFactoryHolder _sessionFactoryHolder;
private readonly IEnumerable<ISessionInterceptor> _interceptors; private readonly IEnumerable<ISessionInterceptor> _interceptors;
private ISession _session; private ISession _session;
private ITransaction _transaction;
private bool _cancelled;
public SessionLocator( public SessionLocator(
ISessionFactoryHolder sessionFactoryHolder, ISessionFactoryHolder sessionFactoryHolder,
@@ -32,19 +30,13 @@ namespace Orchard.Data {
public ISession For(Type entityType) { public ISession For(Type entityType) {
Logger.Debug("Acquiring session for {0}", entityType); Logger.Debug("Acquiring session for {0}", entityType);
Demand();
((ITransactionManager)this).Demand();
return _session; return _session;
} }
public void Demand() { public void Demand() {
EnsureSession(); EnsureSession(IsolationLevel);
if (_transaction == null) {
Logger.Debug("Creating transaction on Demand");
_transaction = _session.BeginTransaction(IsolationLevel);
}
} }
public void RequireNew() { public void RequireNew() {
@@ -52,78 +44,38 @@ namespace Orchard.Data {
} }
public void RequireNew(IsolationLevel level) { public void RequireNew(IsolationLevel level) {
if (_transaction != null) { DisposeSession();
Logger.Debug("New transaction required"); EnsureSession(level);
if (_cancelled) {
if (_transaction != null) {
Logger.Debug("Reverting operations from transaction");
_transaction.Rollback();
_transaction.Dispose();
Logger.Debug("Transaction disposed");
_transaction = null;
}
_cancelled = false;
}
else {
if (_transaction != null) {
Logger.Debug("Marking transaction as complete");
_transaction.Commit();
}
}
DisposeSession();
}
EnsureSession();
Logger.Debug("Creating new transaction with isolation level {0}", level);
_transaction = _session.BeginTransaction(level);
} }
public void Cancel() { public void Cancel() {
Logger.Debug("Transaction cancelled flag set"); Logger.Debug("Rolling back transaction");
_cancelled = true; _session.Transaction.Rollback();
} }
public void Dispose() { public void Dispose() {
if (_transaction != null) {
try {
if (!_cancelled) {
Logger.Debug("Marking transaction as complete");
_transaction.Commit();
}
else {
Logger.Debug("Reverting operations from transaction");
_transaction.Rollback();
}
}
catch (Exception e) {
Logger.Error(e, "Error while disposing the transaction.");
}
finally {
_transaction.Dispose();
Logger.Debug("Transaction disposed");
_transaction = null;
_cancelled = false;
}
}
DisposeSession(); DisposeSession();
} }
private void DisposeSession() { private void DisposeSession() {
if (_session != null) { if (_session != null) {
Logger.Debug("Disposing NHibernate session");
_session.Dispose(); try {
_session = null; if (!_session.Transaction.WasRolledBack && _session.Transaction.IsActive) {
Logger.Debug("Committing transaction");
_session.Transaction.Commit();
}
}
finally {
Logger.Debug("Disposing session");
_session.Close();
_session.Dispose();
_session = null;
}
} }
} }
private void EnsureSession() { private void EnsureSession(IsolationLevel level) {
if (_session != null) { if (_session != null) {
return; return;
} }
@@ -131,6 +83,7 @@ namespace Orchard.Data {
var sessionFactory = _sessionFactoryHolder.GetSessionFactory(); var sessionFactory = _sessionFactoryHolder.GetSessionFactory();
Logger.Debug("Opening NHibernate session"); Logger.Debug("Opening NHibernate session");
_session = sessionFactory.OpenSession(new OrchardSessionInterceptor(_interceptors.ToArray(), Logger)); _session = sessionFactory.OpenSession(new OrchardSessionInterceptor(_interceptors.ToArray(), Logger));
_session.BeginTransaction(level);
} }
class OrchardSessionInterceptor : IInterceptor { class OrchardSessionInterceptor : IInterceptor {