Skip to content

Commit 0b37cec

Browse files
committed
Consistent support for JTA 1.1 TransactionSynchronizationRegistry
JtaTransactionManager's configuration options for a TransactionSynchronizationRegistry are now in sync with the options for UserTransaction/TransactionManager. Specifically, there are setTransactionSynchronizationRegistry/getTransactionSynchronizationRegistry methods for programmatic configuration now. Motivated by Spring's adapting to a Hibernate JtaPlatform, specifically the Hibernate 4.3 changes in that area. Issue: SPR-10839
1 parent 0ac6998 commit 0b37cec

File tree

1 file changed

+64
-23
lines changed

1 file changed

+64
-23
lines changed

spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,11 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
164164

165165
private boolean autodetectTransactionManager = true;
166166

167+
private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry;
168+
167169
private String transactionSynchronizationRegistryName;
168170

169-
private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry;
171+
private boolean autodetectTransactionSynchronizationRegistry = true;
170172

171173
private boolean allowCustomIsolationLevels = false;
172174

@@ -327,7 +329,7 @@ public void setTransactionManager(TransactionManager transactionManager) {
327329
}
328330

329331
/**
330-
* Return the JTA TransactionManager that this transaction manager uses.
332+
* Return the JTA TransactionManager that this transaction manager uses, if any.
331333
*/
332334
public TransactionManager getTransactionManager() {
333335
return this.transactionManager;
@@ -363,6 +365,28 @@ public void setAutodetectTransactionManager(boolean autodetectTransactionManager
363365
this.autodetectTransactionManager = autodetectTransactionManager;
364366
}
365367

368+
/**
369+
* Set the JTA 1.1 TransactionSynchronizationRegistry to use as direct reference.
370+
* <p>A TransactionSynchronizationRegistry allows for interposed registration
371+
* of transaction synchronizations, as an alternative to the regular registration
372+
* methods on the JTA TransactionManager API. Also, it is an official part of the
373+
* Java EE 5 platform, in contrast to the JTA TransactionManager itself.
374+
* <p>Note that the TransactionSynchronizationRegistry will be autodetected in JNDI and
375+
* also from the UserTransaction/TransactionManager object if implemented there as well.
376+
* @see #setTransactionSynchronizationRegistryName
377+
* @see #setAutodetectTransactionSynchronizationRegistry
378+
*/
379+
public void setTransactionSynchronizationRegistry(TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
380+
this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
381+
}
382+
383+
/**
384+
* Return the JTA 1.1 TransactionSynchronizationRegistry that this transaction manager uses, if any.
385+
*/
386+
public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
387+
return this.transactionSynchronizationRegistry;
388+
}
389+
366390
/**
367391
* Set the JNDI name of the JTA 1.1 TransactionSynchronizationRegistry.
368392
* <p>Note that the TransactionSynchronizationRegistry will be autodetected
@@ -374,6 +398,20 @@ public void setTransactionSynchronizationRegistryName(String transactionSynchron
374398
this.transactionSynchronizationRegistryName = transactionSynchronizationRegistryName;
375399
}
376400

401+
/**
402+
* Set whether to autodetect a JTA 1.1 TransactionSynchronizationRegistry object
403+
* at its default JDNI location ("java:comp/TransactionSynchronizationRegistry")
404+
* if the UserTransaction has also been obtained from JNDI, and also whether
405+
* to fall back to checking whether the JTA UserTransaction/TransactionManager
406+
* object implements the JTA TransactionSynchronizationRegistry interface too.
407+
* <p>Default is "true", autodetecting the TransactionSynchronizationRegistry
408+
* unless it has been specified explicitly. Can be turned off to delegate
409+
* synchronization registration to the regular JTA TransactionManager API.
410+
*/
411+
public void setAutodetectTransactionSynchronizationRegistry(boolean autodetectTransactionSynchronizationRegistry) {
412+
this.autodetectTransactionSynchronizationRegistry = autodetectTransactionSynchronizationRegistry;
413+
}
414+
377415
/**
378416
* Set whether to allow custom isolation levels to be specified.
379417
* <p>Default is "false", throwing an exception if a non-default isolation level
@@ -404,38 +442,36 @@ public void afterPropertiesSet() throws TransactionSystemException {
404442
* @throws TransactionSystemException if initialization failed
405443
*/
406444
protected void initUserTransactionAndTransactionManager() throws TransactionSystemException {
407-
// Fetch JTA UserTransaction from JNDI, if necessary.
408445
if (this.userTransaction == null) {
446+
// Fetch JTA UserTransaction from JNDI, if necessary.
409447
if (StringUtils.hasLength(this.userTransactionName)) {
410448
this.userTransaction = lookupUserTransaction(this.userTransactionName);
411449
this.userTransactionObtainedFromJndi = true;
412450
}
413451
else {
414452
this.userTransaction = retrieveUserTransaction();
453+
if (this.userTransaction == null && this.autodetectUserTransaction) {
454+
// Autodetect UserTransaction at its default JNDI location.
455+
this.userTransaction = findUserTransaction();
456+
}
415457
}
416458
}
417459

418-
// Fetch JTA TransactionManager from JNDI, if necessary.
419460
if (this.transactionManager == null) {
461+
// Fetch JTA TransactionManager from JNDI, if necessary.
420462
if (StringUtils.hasLength(this.transactionManagerName)) {
421463
this.transactionManager = lookupTransactionManager(this.transactionManagerName);
422464
}
423465
else {
424466
this.transactionManager = retrieveTransactionManager();
467+
if (this.transactionManager == null && this.autodetectTransactionManager) {
468+
// Autodetect UserTransaction object that implements TransactionManager,
469+
// and check fallback JNDI locations otherwise.
470+
this.transactionManager = findTransactionManager(this.userTransaction);
471+
}
425472
}
426473
}
427474

428-
// Autodetect UserTransaction at its default JNDI location.
429-
if (this.userTransaction == null && this.autodetectUserTransaction) {
430-
this.userTransaction = findUserTransaction();
431-
}
432-
433-
// Autodetect UserTransaction object that implements TransactionManager,
434-
// and check fallback JNDI locations else.
435-
if (this.transactionManager == null && this.autodetectTransactionManager) {
436-
this.transactionManager = findTransactionManager(this.userTransaction);
437-
}
438-
439475
// If only JTA TransactionManager specified, create UserTransaction handle for it.
440476
if (this.userTransaction == null && this.transactionManager != null) {
441477
this.userTransaction = buildUserTransaction(this.transactionManager);
@@ -477,15 +513,20 @@ protected void checkUserTransactionAndTransactionManager() throws IllegalStateEx
477513
* @throws TransactionSystemException if initialization failed
478514
*/
479515
protected void initTransactionSynchronizationRegistry() {
480-
if (StringUtils.hasLength(this.transactionSynchronizationRegistryName)) {
481-
this.transactionSynchronizationRegistry =
482-
lookupTransactionSynchronizationRegistry(this.transactionSynchronizationRegistryName);
483-
}
484-
else {
485-
this.transactionSynchronizationRegistry = retrieveTransactionSynchronizationRegistry();
486-
if (this.transactionSynchronizationRegistry == null) {
516+
if (this.transactionSynchronizationRegistry == null) {
517+
// Fetch JTA TransactionSynchronizationRegistry from JNDI, if necessary.
518+
if (StringUtils.hasLength(this.transactionSynchronizationRegistryName)) {
487519
this.transactionSynchronizationRegistry =
488-
findTransactionSynchronizationRegistry(this.userTransaction, this.transactionManager);
520+
lookupTransactionSynchronizationRegistry(this.transactionSynchronizationRegistryName);
521+
}
522+
else {
523+
this.transactionSynchronizationRegistry = retrieveTransactionSynchronizationRegistry();
524+
if (this.transactionSynchronizationRegistry == null && this.autodetectTransactionSynchronizationRegistry) {
525+
// Autodetect in JNDI if applicable, and check UserTransaction/TransactionManager
526+
// object that implements TransactionSynchronizationRegistry otherwise.
527+
this.transactionSynchronizationRegistry =
528+
findTransactionSynchronizationRegistry(this.userTransaction, this.transactionManager);
529+
}
489530
}
490531
}
491532

0 commit comments

Comments
 (0)