diff --git a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java index 84d75f3498c..d3f35779868 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java +++ b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java @@ -205,21 +205,29 @@ public interface TransactionDefinition { /** * Return the isolation level. - *
Must return one of the {@code ISOLATION_XXX} constants - * defined on {@link TransactionDefinition this interface}. - *
Only makes sense in combination with {@link #PROPAGATION_REQUIRED} - * or {@link #PROPAGATION_REQUIRES_NEW}. + *
Must return one of the {@code ISOLATION_XXX} constants defined on + * {@link TransactionDefinition this interface}. Those constants are designed + * to match the values of the same constants on {@link java.sql.Connection}. + *
Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or + * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started + * transactions. Consider switching the "validateExistingTransactions" flag to + * "true" on your transaction manager if you'd like isolation level declarations + * to get rejected when participating in an existing transaction with a different + * isolation level. *
Note that a transaction manager that does not support custom isolation levels * will throw an exception when given any other level than {@link #ISOLATION_DEFAULT}. * @return the isolation level + * @see #ISOLATION_DEFAULT + * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction */ int getIsolationLevel(); /** * Return the transaction timeout. *
Must return a number of seconds, or {@link #TIMEOUT_DEFAULT}. - *
Only makes sense in combination with {@link #PROPAGATION_REQUIRED} - * or {@link #PROPAGATION_REQUIRES_NEW}. + *
Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or + * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started + * transactions. *
Note that a transaction manager that does not support timeouts will throw * an exception when given any other timeout than {@link #TIMEOUT_DEFAULT}. * @return the transaction timeout @@ -228,13 +236,12 @@ public interface TransactionDefinition { /** * Return whether to optimize as a read-only transaction. - *
The read-only flag applies to any transaction context, whether - * backed by an actual resource transaction - * ({@link #PROPAGATION_REQUIRED}/{@link #PROPAGATION_REQUIRES_NEW}) or - * operating non-transactionally at the resource level - * ({@link #PROPAGATION_SUPPORTS}). In the latter case, the flag will - * only apply to managed resources within the application, such as a - * Hibernate {@code Session}. + *
The read-only flag applies to any transaction context, whether backed + * by an actual resource transaction ({@link #PROPAGATION_REQUIRED}/ + * {@link #PROPAGATION_REQUIRES_NEW}) or operating non-transactionally at + * the resource level ({@link #PROPAGATION_SUPPORTS}). In the latter case, + * the flag will only apply to managed resources within the application, + * such as a Hibernate {@code Session}. *
This just serves as a hint for the actual transaction subsystem; * it will not necessarily cause failure of write access attempts. * A transaction manager which cannot interpret the read-only hint will diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java index 024e376adaf..d2c762e1c04 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 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. @@ -86,19 +86,30 @@ public @interface Transactional { /** * The transaction isolation level. *
Defaults to {@link Isolation#DEFAULT}. + *
Exclusively designed for use with {@link Propagation#REQUIRED} or + * {@link Propagation#REQUIRES_NEW} since it only applies to newly started + * transactions. Consider switching the "validateExistingTransactions" flag to + * "true" on your transaction manager if you'd like isolation level declarations + * to get rejected when participating in an existing transaction with a different + * isolation level. * @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel() + * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction */ Isolation isolation() default Isolation.DEFAULT; /** * The timeout for this transaction. *
Defaults to the default timeout of the underlying transaction system. + *
Exclusively designed for use with {@link Propagation#REQUIRED} or + * {@link Propagation#REQUIRES_NEW} since it only applies to newly started + * transactions. * @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout() */ int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; /** - * {@code true} if the transaction is read-only. + * A boolean flag that can be set to {@code true} if the transaction is + * effectively read-only, allowing for corresponding optimizations at runtime. *
Defaults to {@code false}. *
This just serves as a hint for the actual transaction subsystem; * it will not necessarily cause failure of write access attempts. @@ -106,6 +117,7 @@ public @interface Transactional { * not throw an exception when asked for a read-only transaction * but rather silently ignore the hint. * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly() + * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() */ boolean readOnly() default false; diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java index bad94b05be4..1864f736bb6 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -215,6 +215,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran *
Default is "false", leniently ignoring inner transaction settings, * simply overriding them with the outer transaction's characteristics. * Switch this flag to "true" in order to enforce strict validation. + * @since 2.5.1 */ public final void setValidateExistingTransaction(boolean validateExistingTransaction) { this.validateExistingTransaction = validateExistingTransaction; @@ -223,6 +224,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran /** * Return whether existing transactions should be validated before participating * in them. + * @since 2.5.1 */ public final boolean isValidateExistingTransaction() { return this.validateExistingTransaction; @@ -285,6 +287,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran * boundary. This allows, for example, to continue unit tests even after an * operation failed and the transaction will never be completed. All transaction * managers will only fail earlier if this flag has explicitly been set to "true". + * @since 2.0 * @see org.springframework.transaction.UnexpectedRollbackException */ public final void setFailEarlyOnGlobalRollbackOnly(boolean failEarlyOnGlobalRollbackOnly) { @@ -294,6 +297,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran /** * Return whether to fail early in case of the transaction being globally marked * as rollback-only. + * @since 2.0 */ public final boolean isFailEarlyOnGlobalRollbackOnly() { return this.failEarlyOnGlobalRollbackOnly; diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java index 91c87960cdf..18a9e2759a0 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -110,7 +110,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri * Set the propagation behavior by the name of the corresponding constant in * TransactionDefinition, e.g. "PROPAGATION_REQUIRED". * @param constantName name of the constant - * @exception IllegalArgumentException if the supplied value is not resolvable + * @throws IllegalArgumentException if the supplied value is not resolvable * to one of the {@code PROPAGATION_} constants or is {@code null} * @see #setPropagationBehavior * @see #PROPAGATION_REQUIRED @@ -125,8 +125,16 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri /** * Set the propagation behavior. Must be one of the propagation constants * in the TransactionDefinition interface. Default is PROPAGATION_REQUIRED. - * @exception IllegalArgumentException if the supplied value is not - * one of the {@code PROPAGATION_} constants + *
Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or + * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started + * transactions. Consider switching the "validateExistingTransactions" flag to + * "true" on your transaction manager if you'd like isolation level declarations + * to get rejected when participating in an existing transaction with a different + * isolation level. + *
Note that a transaction manager that does not support custom isolation levels + * will throw an exception when given any other level than {@link #ISOLATION_DEFAULT}. + * @throws IllegalArgumentException if the supplied value is not one of the + * {@code PROPAGATION_} constants * @see #PROPAGATION_REQUIRED */ public final void setPropagationBehavior(int propagationBehavior) { @@ -145,7 +153,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri * Set the isolation level by the name of the corresponding constant in * TransactionDefinition, e.g. "ISOLATION_DEFAULT". * @param constantName name of the constant - * @exception IllegalArgumentException if the supplied value is not resolvable + * @throws IllegalArgumentException if the supplied value is not resolvable * to one of the {@code ISOLATION_} constants or is {@code null} * @see #setIsolationLevel * @see #ISOLATION_DEFAULT @@ -160,8 +168,16 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri /** * Set the isolation level. Must be one of the isolation constants * in the TransactionDefinition interface. Default is ISOLATION_DEFAULT. - * @exception IllegalArgumentException if the supplied value is not - * one of the {@code ISOLATION_} constants + *
Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or + * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started + * transactions. Consider switching the "validateExistingTransactions" flag to + * "true" on your transaction manager if you'd like isolation level declarations + * to get rejected when participating in an existing transaction with a different + * isolation level. + *
Note that a transaction manager that does not support custom isolation levels + * will throw an exception when given any other level than {@link #ISOLATION_DEFAULT}. + * @throws IllegalArgumentException if the supplied value is not one of the + * {@code ISOLATION_} constants * @see #ISOLATION_DEFAULT */ public final void setIsolationLevel(int isolationLevel) { @@ -179,6 +195,11 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri /** * Set the timeout to apply, as number of seconds. * Default is TIMEOUT_DEFAULT (-1). + *
Exclusively designed for use with {@link #PROPAGATION_REQUIRED} or + * {@link #PROPAGATION_REQUIRES_NEW} since it only applies to newly started + * transactions. + *
Note that a transaction manager that does not support timeouts will throw + * an exception when given any other timeout than {@link #TIMEOUT_DEFAULT}. * @see #TIMEOUT_DEFAULT */ public final void setTimeout(int timeout) { @@ -196,6 +217,16 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri /** * Set whether to optimize as read-only transaction. * Default is "false". + *
The read-only flag applies to any transaction context, whether backed + * by an actual resource transaction ({@link #PROPAGATION_REQUIRED}/ + * {@link #PROPAGATION_REQUIRES_NEW}) or operating non-transactionally at + * the resource level ({@link #PROPAGATION_SUPPORTS}). In the latter case, + * the flag will only apply to managed resources within the application, + * such as a Hibernate {@code Session}. + *
This just serves as a hint for the actual transaction subsystem;
+ * it will not necessarily cause failure of write access attempts.
+ * A transaction manager which cannot interpret the read-only hint will
+ * not throw an exception when asked for a read-only transaction.
*/
public final void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
diff --git a/src/docs/asciidoc/data-access.adoc b/src/docs/asciidoc/data-access.adoc
index e267032e79f..e141b48440a 100644
--- a/src/docs/asciidoc/data-access.adoc
+++ b/src/docs/asciidoc/data-access.adoc
@@ -195,9 +195,6 @@ execution.
The `TransactionDefinition` interface specifies:
-* __Isolation__: The degree to which this transaction is isolated from the work of other
- transactions. For example, can this transaction see uncommitted writes from other
- transactions?
* __Propagation__: Typically, all code executed within a transaction scope will run in
that transaction. However, you have the option of specifying the behavior in the event
that a transactional method is executed when a transaction context already exists. For
@@ -205,6 +202,9 @@ The `TransactionDefinition` interface specifies:
the existing transaction can be suspended and a new transaction created. __Spring
offers all of the transaction propagation options familiar from EJB CMT__. To read
about the semantics of transaction propagation in Spring, see <