mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Fixing migration isolation and sessions lifetime
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user