Browse Source

Add early support for JTA 2.1 read-only attribute

Closes gh-35633
pull/35641/head
Juergen Hoeller 2 months ago
parent
commit
001fc8e585
  1. 4
      spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java
  2. 37
      spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionManager.java
  3. 2
      spring-tx/src/main/java/org/springframework/transaction/jta/JtaTransactionObject.java

4
spring-tx/src/main/java/org/springframework/transaction/annotation/JtaTransactionAnnotationParser.java

@ -78,6 +78,10 @@ public class JtaTransactionAnnotationParser implements TransactionAnnotationPars @@ -78,6 +78,10 @@ public class JtaTransactionAnnotationParser implements TransactionAnnotationPars
}
rbta.setRollbackRules(rollbackRules);
if (attributes.containsKey("readOnly")) { // JTA 2.1
rbta.setReadOnly(attributes.getBoolean("readOnly"));
}
return rbta;
}

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

@ -19,6 +19,8 @@ package org.springframework.transaction.jta; @@ -19,6 +19,8 @@ package org.springframework.transaction.jta;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;
@ -52,6 +54,8 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage @@ -52,6 +54,8 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
@ -139,6 +143,10 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager @@ -139,6 +143,10 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
"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 @Nullable UserTransaction userTransaction;
@ -858,6 +866,12 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager @@ -858,6 +866,12 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
applyIsolationLevel(txObject, definition.getIsolationLevel());
int timeout = determineTimeout(definition);
applyTimeout(txObject, timeout);
if (definition.isReadOnly()) {
setReadOnlyIfPossible(txObject.getUserTransaction(), true);
txObject.resetReadOnly = true;
}
txObject.getUserTransaction().begin();
}
@ -904,6 +918,21 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager @@ -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
protected Object doSuspend(Object transaction) {
@ -1161,6 +1190,14 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager @@ -1161,6 +1190,14 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
@Override
protected void doCleanupAfterCompletion(Object 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) {
try {
txObject.getUserTransaction().setTransactionTimeout(0);

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

@ -41,6 +41,8 @@ public class JtaTransactionObject implements SmartTransactionObject { @@ -41,6 +41,8 @@ public class JtaTransactionObject implements SmartTransactionObject {
boolean resetTransactionTimeout = false;
boolean resetReadOnly = false;
/**
* Create a new JtaTransactionObject for the given JTA UserTransaction.

Loading…
Cancel
Save