|
|
|
@ -19,6 +19,8 @@ package org.springframework.transaction.jta; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.ObjectInputStream; |
|
|
|
import java.io.ObjectInputStream; |
|
|
|
import java.io.Serializable; |
|
|
|
import java.io.Serializable; |
|
|
|
|
|
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Properties; |
|
|
|
import java.util.Properties; |
|
|
|
|
|
|
|
|
|
|
|
@ -52,6 +54,8 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage |
|
|
|
import org.springframework.transaction.support.DefaultTransactionStatus; |
|
|
|
import org.springframework.transaction.support.DefaultTransactionStatus; |
|
|
|
import org.springframework.transaction.support.TransactionSynchronization; |
|
|
|
import org.springframework.transaction.support.TransactionSynchronization; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -139,6 +143,10 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager |
|
|
|
"java:comp/TransactionSynchronizationRegistry"; |
|
|
|
"java:comp/TransactionSynchronizationRegistry"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// JTA 2.1 UserTransaction#setReadOnly(boolean) method available?
|
|
|
|
|
|
|
|
private static final @Nullable Method setReadOnlyMethod = |
|
|
|
|
|
|
|
ClassUtils.getMethodIfAvailable(UserTransaction.class, "setReadOnly", boolean.class); |
|
|
|
|
|
|
|
|
|
|
|
private transient JndiTemplate jndiTemplate = new JndiTemplate(); |
|
|
|
private transient JndiTemplate jndiTemplate = new JndiTemplate(); |
|
|
|
|
|
|
|
|
|
|
|
private transient @Nullable UserTransaction userTransaction; |
|
|
|
private transient @Nullable UserTransaction userTransaction; |
|
|
|
@ -858,6 +866,12 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager |
|
|
|
applyIsolationLevel(txObject, definition.getIsolationLevel()); |
|
|
|
applyIsolationLevel(txObject, definition.getIsolationLevel()); |
|
|
|
int timeout = determineTimeout(definition); |
|
|
|
int timeout = determineTimeout(definition); |
|
|
|
applyTimeout(txObject, timeout); |
|
|
|
applyTimeout(txObject, timeout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (definition.isReadOnly()) { |
|
|
|
|
|
|
|
setReadOnlyIfPossible(txObject.getUserTransaction(), true); |
|
|
|
|
|
|
|
txObject.resetReadOnly = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
txObject.getUserTransaction().begin(); |
|
|
|
txObject.getUserTransaction().begin(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -904,6 +918,21 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void setReadOnlyIfPossible(UserTransaction ut, boolean readOnly) throws SystemException { |
|
|
|
|
|
|
|
if (setReadOnlyMethod != null) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
setReadOnlyMethod.invoke(ut, readOnly); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (Exception ex) { |
|
|
|
|
|
|
|
if (ex instanceof InvocationTargetException ute && |
|
|
|
|
|
|
|
ute.getTargetException() instanceof SystemException se) { |
|
|
|
|
|
|
|
throw se; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ReflectionUtils.handleReflectionException(ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected Object doSuspend(Object transaction) { |
|
|
|
protected Object doSuspend(Object transaction) { |
|
|
|
@ -1161,6 +1190,14 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
protected void doCleanupAfterCompletion(Object transaction) { |
|
|
|
protected void doCleanupAfterCompletion(Object transaction) { |
|
|
|
JtaTransactionObject txObject = (JtaTransactionObject) transaction; |
|
|
|
JtaTransactionObject txObject = (JtaTransactionObject) transaction; |
|
|
|
|
|
|
|
if (txObject.resetReadOnly) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
setReadOnlyIfPossible(txObject.getUserTransaction(), false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (SystemException ex) { |
|
|
|
|
|
|
|
logger.debug("Failed to reset read-only flag after after JTA completion", ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (txObject.resetTransactionTimeout) { |
|
|
|
if (txObject.resetTransactionTimeout) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
txObject.getUserTransaction().setTransactionTimeout(0); |
|
|
|
txObject.getUserTransaction().setTransactionTimeout(0); |
|
|
|
|