Skip to content

Commit 5165465

Browse files
committed
initialize synchronization after begin while instantiating TransactionStatus as early as possible (SPR-6409)
1 parent d67e655 commit 5165465

File tree

1 file changed

+41
-56
lines changed

1 file changed

+41
-56
lines changed

org.springframework.transaction/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -361,28 +361,22 @@ else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATIO
361361
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
362362
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
363363
SuspendedResourcesHolder suspendedResources = suspend(null);
364-
DefaultTransactionStatus status = null;
364+
if (debugEnabled) {
365+
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
366+
}
365367
try {
366-
if (debugEnabled) {
367-
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
368-
}
369368
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
370-
status = newTransactionStatus(
369+
DefaultTransactionStatus status = instantiateTransactionStatus(
371370
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
372371
doBegin(transaction, definition);
372+
prepareSynchronization(status, definition);
373373
return status;
374374
}
375375
catch (RuntimeException ex) {
376-
if (status != null && status.isNewSynchronization()) {
377-
TransactionSynchronizationManager.clear();
378-
}
379376
resume(null, suspendedResources);
380377
throw ex;
381378
}
382379
catch (Error err) {
383-
if (status != null && status.isNewSynchronization()) {
384-
TransactionSynchronizationManager.clear();
385-
}
386380
resume(null, suspendedResources);
387381
throw err;
388382
}
@@ -422,25 +416,19 @@ private TransactionStatus handleExistingTransaction(
422416
definition.getName() + "]");
423417
}
424418
SuspendedResourcesHolder suspendedResources = suspend(transaction);
425-
DefaultTransactionStatus status = null;
426419
try {
427420
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
428-
status = newTransactionStatus(
421+
DefaultTransactionStatus status = instantiateTransactionStatus(
429422
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
430423
doBegin(transaction, definition);
424+
prepareSynchronization(status, definition);
431425
return status;
432426
}
433427
catch (RuntimeException beginEx) {
434-
if (status != null && status.isNewSynchronization()) {
435-
TransactionSynchronizationManager.clear();
436-
}
437428
resumeAfterBeginException(transaction, suspendedResources, beginEx);
438429
throw beginEx;
439430
}
440431
catch (Error beginErr) {
441-
if (status != null && status.isNewSynchronization()) {
442-
TransactionSynchronizationManager.clear();
443-
}
444432
resumeAfterBeginException(transaction, suspendedResources, beginErr);
445433
throw beginErr;
446434
}
@@ -469,23 +457,10 @@ private TransactionStatus handleExistingTransaction(
469457
// Usually only for JTA: Spring synchronization might get activated here
470458
// in case of a pre-existing JTA transaction.
471459
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
472-
DefaultTransactionStatus status = newTransactionStatus(
460+
DefaultTransactionStatus status = instantiateTransactionStatus(
473461
definition, transaction, true, newSynchronization, debugEnabled, null);
474-
try {
475-
doBegin(transaction, definition);
476-
}
477-
catch (RuntimeException beginEx) {
478-
if (status != null && status.isNewSynchronization()) {
479-
TransactionSynchronizationManager.clear();
480-
}
481-
throw beginEx;
482-
}
483-
catch (Error beginErr) {
484-
if (status != null && status.isNewSynchronization()) {
485-
TransactionSynchronizationManager.clear();
486-
}
487-
throw beginErr;
488-
}
462+
doBegin(transaction, definition);
463+
prepareSynchronization(status, definition);
489464
return status;
490465
}
491466
}
@@ -519,34 +494,44 @@ private TransactionStatus handleExistingTransaction(
519494

520495
/**
521496
* Create a new TransactionStatus for the given arguments,
522-
* initializing transaction synchronization as appropriate.
497+
* also initializing transaction synchronization as appropriate.
523498
*/
524499
protected DefaultTransactionStatus newTransactionStatus(
525500
TransactionDefinition definition, Object transaction, boolean newTransaction,
526501
boolean newSynchronization, boolean debug, Object suspendedResources) {
527502

503+
DefaultTransactionStatus status = instantiateTransactionStatus(
504+
definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
505+
prepareSynchronization(status, definition);
506+
return status;
507+
}
508+
509+
/**
510+
* Create a rae TransactionStatus instance for the given arguments.
511+
*/
512+
private DefaultTransactionStatus instantiateTransactionStatus(
513+
TransactionDefinition definition, Object transaction, boolean newTransaction,
514+
boolean newSynchronization, boolean debug, Object suspendedResources) {
515+
528516
boolean actualNewSynchronization = newSynchronization &&
529517
!TransactionSynchronizationManager.isSynchronizationActive();
530-
try {
531-
if (actualNewSynchronization) {
532-
TransactionSynchronizationManager.setActualTransactionActive(transaction != null);
533-
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
534-
(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?
535-
definition.getIsolationLevel() : null);
536-
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
537-
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
538-
TransactionSynchronizationManager.initSynchronization();
539-
}
540-
return new DefaultTransactionStatus(
541-
transaction, newTransaction, actualNewSynchronization,
542-
definition.isReadOnly(), debug, suspendedResources);
543-
}
544-
catch (Error err) {
545-
// Can only really be an OutOfMemoryError...
546-
if (actualNewSynchronization) {
547-
TransactionSynchronizationManager.clear();
548-
}
549-
throw err;
518+
return new DefaultTransactionStatus(
519+
transaction, newTransaction, actualNewSynchronization,
520+
definition.isReadOnly(), debug, suspendedResources);
521+
}
522+
523+
/**
524+
* Initialize transaction synchronization as appropriate.
525+
*/
526+
private void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
527+
if (status.isNewSynchronization()) {
528+
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
529+
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
530+
(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) ?
531+
definition.getIsolationLevel() : null);
532+
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
533+
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
534+
TransactionSynchronizationManager.initSynchronization();
550535
}
551536
}
552537

0 commit comments

Comments
 (0)