Browse Source

Introduce TransactionDefinition.withDefaults() shortcut

Such a static unmodifiable TransactionDefinition with defaults can be used for getTransaction(null) calls, now also possible for getReactiveTransaction. Furthermore, it can be used for a simple TransactionalOperator.create(ReactiveTransactionManager) method without an internal dependency on the transaction.support package.

See gh-22646
pull/22881/head
Juergen Hoeller 7 years ago
parent
commit
a2a6bc3d47
  1. 6
      spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java
  2. 7
      spring-tx/src/main/java/org/springframework/transaction/ReactiveTransactionManager.java
  3. 33
      spring-tx/src/main/java/org/springframework/transaction/StaticTransactionDefinition.java
  4. 44
      spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java
  5. 23
      spring-tx/src/main/java/org/springframework/transaction/jta/WebSphereUowTransactionManager.java
  6. 35
      spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java
  7. 40
      spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionalOperator.java
  8. 42
      spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java

6
spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,9 +41,9 @@ import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/** /**
* Common base class for accessing a Quartz Scheduler, i.e. for registering jobs, * Common base class for accessing a Quartz Scheduler, i.e. for registering jobs,
@ -207,7 +207,7 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
protected void registerJobsAndTriggers() throws SchedulerException { protected void registerJobsAndTriggers() throws SchedulerException {
TransactionStatus transactionStatus = null; TransactionStatus transactionStatus = null;
if (this.transactionManager != null) { if (this.transactionManager != null) {
transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition()); transactionStatus = this.transactionManager.getTransaction(TransactionDefinition.withDefaults());
} }
try { try {

7
spring-tx/src/main/java/org/springframework/transaction/ReactiveTransactionManager.java

@ -18,6 +18,8 @@ package org.springframework.transaction;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.lang.Nullable;
/** /**
* This is the central interface in Spring's reactive transaction infrastructure. * This is the central interface in Spring's reactive transaction infrastructure.
* Applications can use this directly, but it is not primarily meant as API: * Applications can use this directly, but it is not primarily meant as API:
@ -27,6 +29,8 @@ import reactor.core.publisher.Mono;
* @author Mark Paluch * @author Mark Paluch
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 5.2 * @since 5.2
* @see org.springframework.transaction.reactive.TransactionalOperator
* @see org.springframework.transaction.interceptor.TransactionInterceptor
*/ */
public interface ReactiveTransactionManager extends TransactionManager { public interface ReactiveTransactionManager extends TransactionManager {
@ -53,7 +57,8 @@ public interface ReactiveTransactionManager extends TransactionManager {
* @see TransactionDefinition#getTimeout * @see TransactionDefinition#getTimeout
* @see TransactionDefinition#isReadOnly * @see TransactionDefinition#isReadOnly
*/ */
Mono<ReactiveTransaction> getReactiveTransaction(TransactionDefinition definition) throws TransactionException; Mono<ReactiveTransaction> getReactiveTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
/** /**
* Commit the given transaction, with regard to its status. If the transaction * Commit the given transaction, with regard to its status. If the transaction

33
spring-tx/src/main/java/org/springframework/transaction/StaticTransactionDefinition.java

@ -0,0 +1,33 @@
/*
* Copyright 2002-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction;
/**
* A static unmodifiable transaction definition.
*
* @author Juergen Hoeller
* @since 5.2
* @see TransactionDefinition#withDefaults()
*/
final class StaticTransactionDefinition implements TransactionDefinition {
static final StaticTransactionDefinition INSTANCE = new StaticTransactionDefinition();
private StaticTransactionDefinition() {
}
}

44
spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java

@ -195,11 +195,14 @@ public interface TransactionDefinition {
* Return the propagation behavior. * Return the propagation behavior.
* <p>Must return one of the {@code PROPAGATION_XXX} constants * <p>Must return one of the {@code PROPAGATION_XXX} constants
* defined on {@link TransactionDefinition this interface}. * defined on {@link TransactionDefinition this interface}.
* <p>The default is {@link #PROPAGATION_REQUIRED}.
* @return the propagation behavior * @return the propagation behavior
* @see #PROPAGATION_REQUIRED * @see #PROPAGATION_REQUIRED
* @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive() * @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive()
*/ */
int getPropagationBehavior(); default int getPropagationBehavior() {
return PROPAGATION_REQUIRED;
}
/** /**
* Return the isolation level. * Return the isolation level.
@ -212,13 +215,16 @@ public interface TransactionDefinition {
* "true" on your transaction manager if you'd like isolation level declarations * "true" on your transaction manager if you'd like isolation level declarations
* to get rejected when participating in an existing transaction with a different * to get rejected when participating in an existing transaction with a different
* isolation level. * isolation level.
* <p>Note that a transaction manager that does not support custom isolation levels * <p>The default is {@link #ISOLATION_DEFAULT}. Note that a transaction manager
* will throw an exception when given any other level than {@link #ISOLATION_DEFAULT}. * that does not support custom isolation levels will throw an exception when
* given any other level than {@link #ISOLATION_DEFAULT}.
* @return the isolation level * @return the isolation level
* @see #ISOLATION_DEFAULT * @see #ISOLATION_DEFAULT
* @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction
*/ */
int getIsolationLevel(); default int getIsolationLevel() {
return ISOLATION_DEFAULT;
}
/** /**
* Return the transaction timeout. * Return the transaction timeout.
@ -228,9 +234,12 @@ public interface TransactionDefinition {
* transactions. * transactions.
* <p>Note that a transaction manager that does not support timeouts will throw * <p>Note that a transaction manager that does not support timeouts will throw
* an exception when given any other timeout than {@link #TIMEOUT_DEFAULT}. * an exception when given any other timeout than {@link #TIMEOUT_DEFAULT}.
* <p>The default is {@link #TIMEOUT_DEFAULT}.
* @return the transaction timeout * @return the transaction timeout
*/ */
int getTimeout(); default int getTimeout() {
return TIMEOUT_DEFAULT;
}
/** /**
* Return whether to optimize as a read-only transaction. * Return whether to optimize as a read-only transaction.
@ -245,10 +254,13 @@ public interface TransactionDefinition {
* A transaction manager which cannot interpret the read-only hint will * A transaction manager which cannot interpret the read-only hint will
* <i>not</i> throw an exception when asked for a read-only transaction. * <i>not</i> throw an exception when asked for a read-only transaction.
* @return {@code true} if the transaction is to be optimized as read-only * @return {@code true} if the transaction is to be optimized as read-only
* ({@code false} by default)
* @see org.springframework.transaction.support.TransactionSynchronization#beforeCommit(boolean) * @see org.springframework.transaction.support.TransactionSynchronization#beforeCommit(boolean)
* @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly()
*/ */
boolean isReadOnly(); default boolean isReadOnly() {
return false;
}
/** /**
* Return the name of this transaction. Can be {@code null}. * Return the name of this transaction. Can be {@code null}.
@ -256,11 +268,27 @@ public interface TransactionDefinition {
* transaction monitor, if applicable (for example, WebLogic's). * transaction monitor, if applicable (for example, WebLogic's).
* <p>In case of Spring's declarative transactions, the exposed name will be * <p>In case of Spring's declarative transactions, the exposed name will be
* the {@code fully-qualified class name + "." + method name} (by default). * the {@code fully-qualified class name + "." + method name} (by default).
* @return the name of this transaction * @return the name of this transaction ({@code null} by default}
* @see org.springframework.transaction.interceptor.TransactionAspectSupport * @see org.springframework.transaction.interceptor.TransactionAspectSupport
* @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionName() * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionName()
*/ */
@Nullable @Nullable
String getName(); default String getName() {
return null;
}
// Static builder methods
/**
* Return an unmodifiable {@code TransactionDefinition} with defaults.
* <p>For customization purposes, use the modifiable
* {@link org.springframework.transaction.support.DefaultTransactionDefinition}
* instead.
* @since 5.2
*/
static TransactionDefinition withDefaults() {
return StaticTransactionDefinition.INSTANCE;
}
} }

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,7 +34,6 @@ import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.TransactionSystemException;
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager; import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus; import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.SmartTransactionObject; import org.springframework.transaction.support.SmartTransactionObject;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
@ -233,17 +232,15 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
public <T> T execute(@Nullable TransactionDefinition definition, TransactionCallback<T> callback) public <T> T execute(@Nullable TransactionDefinition definition, TransactionCallback<T> callback)
throws TransactionException { throws TransactionException {
if (definition == null) { // Use defaults if no transaction definition given.
// Use defaults if no transaction definition given. TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
definition = new DefaultTransactionDefinition();
}
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
} }
UOWManager uowManager = obtainUOWManager(); UOWManager uowManager = obtainUOWManager();
int pb = definition.getPropagationBehavior(); int pb = def.getPropagationBehavior();
boolean existingTx = (uowManager.getUOWStatus() != UOWSynchronizationRegistry.UOW_STATUS_NONE && boolean existingTx = (uowManager.getUOWStatus() != UOWSynchronizationRegistry.UOW_STATUS_NONE &&
uowManager.getUOWType() != UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION); uowManager.getUOWType() != UOWSynchronizationRegistry.UOW_TYPE_LOCAL_TRANSACTION);
@ -292,19 +289,19 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
boolean debug = logger.isDebugEnabled(); boolean debug = logger.isDebugEnabled();
if (debug) { if (debug) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
} }
SuspendedResourcesHolder suspendedResources = (!joinTx ? suspend(null) : null); SuspendedResourcesHolder suspendedResources = (!joinTx ? suspend(null) : null);
UOWActionAdapter<T> action = null; UOWActionAdapter<T> action = null;
try { try {
if (definition.getTimeout() > TransactionDefinition.TIMEOUT_DEFAULT) { if (def.getTimeout() > TransactionDefinition.TIMEOUT_DEFAULT) {
uowManager.setUOWTimeout(uowType, definition.getTimeout()); uowManager.setUOWTimeout(uowType, def.getTimeout());
} }
if (debug) { if (debug) {
logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx); logger.debug("Invoking WebSphere UOW action: type=" + uowType + ", join=" + joinTx);
} }
action = new UOWActionAdapter<>( action = new UOWActionAdapter<>(
definition, callback, (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION), !joinTx, newSynch, debug); def, callback, (uowType == UOWManager.UOW_TYPE_GLOBAL_TRANSACTION), !joinTx, newSynch, debug);
uowManager.runUnderUOW(uowType, joinTx, action); uowManager.runUnderUOW(uowType, joinTx, action);
if (debug) { if (debug) {
logger.debug("Returned from WebSphere UOW action: type=" + uowType + ", join=" + joinTx); logger.debug("Returned from WebSphere UOW action: type=" + uowType + ", join=" + joinTx);

35
spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java

@ -95,7 +95,12 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran
* @see #doBegin * @see #doBegin
*/ */
@Override @Override
public final Mono<ReactiveTransaction> getReactiveTransaction(TransactionDefinition definition) throws TransactionException { public final Mono<ReactiveTransaction> getReactiveTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// Use defaults if no transaction definition given.
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
return TransactionSynchronizationManager.currentTransaction() return TransactionSynchronizationManager.currentTransaction()
.flatMap(synchronizationManager -> { .flatMap(synchronizationManager -> {
@ -106,22 +111,22 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran
if (isExistingTransaction(transaction)) { if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave. // Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(synchronizationManager, definition, transaction, debugEnabled); return handleExistingTransaction(synchronizationManager, def, transaction, debugEnabled);
} }
// Check definition settings for new transaction. // Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
return Mono.error(new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout())); return Mono.error(new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout()));
} }
// No existing transaction found -> check propagation behavior to find out how to proceed. // No existing transaction found -> check propagation behavior to find out how to proceed.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
return Mono.error(new IllegalTransactionStateException( return Mono.error(new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'")); "No existing transaction found for transaction marked with propagation 'mandatory'"));
} }
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
return TransactionContextManager.currentContext() return TransactionContextManager.currentContext()
.map(TransactionSynchronizationManager::new) .map(TransactionSynchronizationManager::new)
@ -131,14 +136,14 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran
.defaultIfEmpty(Optional.empty()) .defaultIfEmpty(Optional.empty())
.flatMap(suspendedResources -> { .flatMap(suspendedResources -> {
if (debugEnabled) { if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
} }
return Mono.defer(() -> { return Mono.defer(() -> {
GenericReactiveTransaction status = newReactiveTransaction( GenericReactiveTransaction status = newReactiveTransaction(
nestedSynchronizationManager, definition, transaction, true, nestedSynchronizationManager, def, transaction, true,
debugEnabled, suspendedResources.orElse(null)); debugEnabled, suspendedResources.orElse(null));
return doBegin(nestedSynchronizationManager, transaction, definition) return doBegin(nestedSynchronizationManager, transaction, def)
.doOnSuccess(ignore -> prepareSynchronization(nestedSynchronizationManager, status, definition)) .doOnSuccess(ignore -> prepareSynchronization(nestedSynchronizationManager, status, def))
.thenReturn(status); .thenReturn(status);
}).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR, }).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR,
ex -> resume(nestedSynchronizationManager, null, suspendedResources.orElse(null)) ex -> resume(nestedSynchronizationManager, null, suspendedResources.orElse(null))
@ -147,11 +152,11 @@ public abstract class AbstractReactiveTransactionManager implements ReactiveTran
} }
else { else {
// Create "empty" transaction: no actual transaction, but potentially synchronization. // Create "empty" transaction: no actual transaction, but potentially synchronization.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) { if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " + logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition); "isolation level will effectively be ignored: " + def);
} }
return Mono.just(prepareReactiveTransaction(synchronizationManager, definition, null, true, debugEnabled, null)); return Mono.just(prepareReactiveTransaction(synchronizationManager, def, null, true, debugEnabled, null));
} }
}); });
} }

40
spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionalOperator.java

@ -46,20 +46,6 @@ import org.springframework.transaction.TransactionException;
*/ */
public interface TransactionalOperator { public interface TransactionalOperator {
/**
* Create a new {@link TransactionalOperator} using {@link ReactiveTransactionManager}
* and {@link TransactionDefinition}.
* @param transactionManager the transaction management strategy to be used
* @param transactionDefinition the transaction definition to apply
* @return the transactional operator
*/
static TransactionalOperator create(
ReactiveTransactionManager transactionManager, TransactionDefinition transactionDefinition){
return new TransactionalOperatorImpl(transactionManager, transactionDefinition);
}
/** /**
* Wrap the functional sequence specified by the given Flux within a transaction. * Wrap the functional sequence specified by the given Flux within a transaction.
* @param flux the Flux that should be executed within the transaction * @param flux the Flux that should be executed within the transaction
@ -95,4 +81,30 @@ public interface TransactionalOperator {
*/ */
<T> Flux<T> execute(TransactionCallback<T> action) throws TransactionException; <T> Flux<T> execute(TransactionCallback<T> action) throws TransactionException;
// Static builder methods
/**
* Create a new {@link TransactionalOperator} using {@link ReactiveTransactionManager},
* using a default transaction.
* @param transactionManager the transaction management strategy to be used
* @return the transactional operator
*/
static TransactionalOperator create(ReactiveTransactionManager transactionManager){
return create(transactionManager, TransactionDefinition.withDefaults());
}
/**
* Create a new {@link TransactionalOperator} using {@link ReactiveTransactionManager}
* and {@link TransactionDefinition}.
* @param transactionManager the transaction management strategy to be used
* @param transactionDefinition the transaction definition to apply
* @return the transactional operator
*/
static TransactionalOperator create(
ReactiveTransactionManager transactionManager, TransactionDefinition transactionDefinition){
return new TransactionalOperatorImpl(transactionManager, transactionDefinition);
}
} }

42
spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java

@ -338,45 +338,43 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
* @see #doBegin * @see #doBegin
*/ */
@Override @Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
Object transaction = doGetTransaction(); throws TransactionException {
// Cache debug flag to avoid repeated checks. // Use defaults if no transaction definition given.
boolean debugEnabled = logger.isDebugEnabled(); TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
if (definition == null) { Object transaction = doGetTransaction();
// Use defaults if no transaction definition given. boolean debugEnabled = logger.isDebugEnabled();
definition = new DefaultTransactionDefinition();
}
if (isExistingTransaction(transaction)) { if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave. // Existing transaction found -> check propagation behavior to find out how to behave.
return handleExistingTransaction(definition, transaction, debugEnabled); return handleExistingTransaction(def, transaction, debugEnabled);
} }
// Check definition settings for new transaction. // Check definition settings for new transaction.
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
} }
// No existing transaction found -> check propagation behavior to find out how to proceed. // No existing transaction found -> check propagation behavior to find out how to proceed.
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException( throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'"); "No existing transaction found for transaction marked with propagation 'mandatory'");
} }
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null); SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) { if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
} }
try { try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus( DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); def, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition); doBegin(transaction, def);
prepareSynchronization(status, definition); prepareSynchronization(status, def);
return status; return status;
} }
catch (RuntimeException | Error ex) { catch (RuntimeException | Error ex) {
@ -386,12 +384,12 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
} }
else { else {
// Create "empty" transaction: no actual transaction, but potentially synchronization. // Create "empty" transaction: no actual transaction, but potentially synchronization.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) { if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " + logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition); "isolation level will effectively be ignored: " + def);
} }
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null); return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
} }
} }

Loading…
Cancel
Save