SimpleTransactionScope properly suspends and resumes scoped objects

Issue: SPR-14148
This commit is contained in:
Juergen Hoeller
2016-04-12 16:02:36 +02:00
parent 10554a85c9
commit 831f09cf48
2 changed files with 93 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ public class SimpleTransactionScope implements Scope {
ScopedObjectsHolder scopedObjects = (ScopedObjectsHolder) TransactionSynchronizationManager.getResource(this);
if (scopedObjects == null) {
scopedObjects = new ScopedObjectsHolder();
TransactionSynchronizationManager.registerSynchronization(new CleanupSynchronization());
TransactionSynchronizationManager.registerSynchronization(new CleanupSynchronization(scopedObjects));
TransactionSynchronizationManager.bindResource(this, scopedObjects);
}
Object scopedObject = scopedObjects.scopedInstances.get(name);
@@ -98,13 +98,30 @@ public class SimpleTransactionScope implements Scope {
private class CleanupSynchronization extends TransactionSynchronizationAdapter {
private final ScopedObjectsHolder scopedObjects;
public CleanupSynchronization(ScopedObjectsHolder scopedObjects) {
this.scopedObjects = scopedObjects;
}
@Override
public void suspend() {
TransactionSynchronizationManager.unbindResource(SimpleTransactionScope.this);
}
@Override
public void resume() {
TransactionSynchronizationManager.bindResource(SimpleTransactionScope.this, this.scopedObjects);
}
@Override
public void afterCompletion(int status) {
ScopedObjectsHolder scopedObjects = (ScopedObjectsHolder)
TransactionSynchronizationManager.unbindResourceIfPossible(SimpleTransactionScope.this);
for (Runnable callback : scopedObjects.destructionCallbacks.values()) {
TransactionSynchronizationManager.unbindResourceIfPossible(SimpleTransactionScope.this);
for (Runnable callback : this.scopedObjects.destructionCallbacks.values()) {
callback.run();
}
this.scopedObjects.destructionCallbacks.clear();
this.scopedObjects.scopedInstances.clear();
}
}