📄 abstractplatformtransactionmanager.java
字号:
}
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"Transaction propagation 'mandatory' but no existing transaction found");
}
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (debugEnabled) {
logger.debug("Creating new transaction");
}
doBegin(transaction, definition);
boolean newSynchronization = (this.transactionSynchronization != SYNCHRONIZATION_NEVER);
return newTransactionStatus(
transaction, true, newSynchronization, definition.isReadOnly(), debugEnabled, null);
}
else {
// "empty" (-> no) transaction
boolean newSynchronization = (this.transactionSynchronization == SYNCHRONIZATION_ALWAYS);
return newTransactionStatus(
null, false, newSynchronization, definition.isReadOnly(), debugEnabled, null);
}
}
/**
* Create a new TransactionStatus for the given arguments,
* initializing transaction synchronization if appropriate.
*/
private DefaultTransactionStatus newTransactionStatus(
Object transaction, boolean newTransaction, boolean newSynchronization,
boolean readOnly, boolean debug, Object suspendedResources) {
boolean actualNewSynchronization = newSynchronization &&
!TransactionSynchronizationManager.isSynchronizationActive();
if (actualNewSynchronization) {
TransactionSynchronizationManager.initSynchronization();
}
return new DefaultTransactionStatus(
transaction, newTransaction, actualNewSynchronization, readOnly, debug, suspendedResources);
}
/**
* Suspend the given transaction. Suspends transaction synchronization first,
* then delegates to the doSuspend template method.
* @param transaction the current transaction object
* @return an object that holds suspended resources
* @see #doSuspend
* @see #resume
*/
private Object suspend(Object transaction) throws TransactionException {
List suspendedSynchronizations = null;
Object holder = doSuspend(transaction);
if (TransactionSynchronizationManager.isSynchronizationActive()) {
suspendedSynchronizations = TransactionSynchronizationManager.getSynchronizations();
for (Iterator it = suspendedSynchronizations.iterator(); it.hasNext();) {
((TransactionSynchronization) it.next()).suspend();
}
TransactionSynchronizationManager.clearSynchronization();
}
return new SuspendedResourcesHolder(suspendedSynchronizations, holder);
}
/**
* Resume the given transaction. Delegates to the doResume template method
* first, then resuming transaction synchronization.
* @param transaction the current transaction object
* @param suspendedResources the object that holds suspended resources,
* as returned by suspend
* @see #doResume
* @see #suspend
*/
private void resume(Object transaction, Object suspendedResources) throws TransactionException {
SuspendedResourcesHolder resourcesHolder = (SuspendedResourcesHolder) suspendedResources;
if (resourcesHolder.getSuspendedSynchronizations() != null) {
TransactionSynchronizationManager.initSynchronization();
for (Iterator it = resourcesHolder.getSuspendedSynchronizations().iterator(); it.hasNext();) {
TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
synchronization.resume();
TransactionSynchronizationManager.registerSynchronization(synchronization);
}
}
doResume(transaction, resourcesHolder.getSuspendedResources());
}
/**
* This implementation of commit handles participating in existing
* transactions and programmatic rollback requests.
* Delegates to isRollbackOnly, doCommit and rollback.
* @see org.springframework.transaction.TransactionStatus#isRollbackOnly
* @see #doCommit
* @see #rollback
*/
public final void commit(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
if (status.isRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
rollback(status);
}
else {
try {
boolean beforeCompletionInvoked = false;
try {
triggerBeforeCommit(defStatus);
triggerBeforeCompletion(defStatus, null);
beforeCompletionInvoked = true;
if (defStatus.hasSavepoint()) {
if (defStatus.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
defStatus.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
logger.debug("Initiating transaction commit");
doCommit(defStatus);
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_ROLLED_BACK, ex);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(defStatus, ex);
}
else {
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, ex);
}
throw ex;
}
catch (RuntimeException ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(defStatus, ex);
}
doRollbackOnCommitException(defStatus, ex);
throw ex;
}
catch (Error err) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(defStatus, err);
}
doRollbackOnCommitException(defStatus, err);
throw err;
}
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_COMMITTED, null);
}
finally {
cleanupAfterCompletion(defStatus);
}
}
}
/**
* This implementation of rollback handles participating in existing
* transactions. Delegates to doRollback and doSetRollbackOnly.
* @see #doRollback
* @see #doSetRollbackOnly
*/
public final void rollback(TransactionStatus status) throws TransactionException {
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
try {
try {
triggerBeforeCompletion(defStatus, null);
if (defStatus.hasSavepoint()) {
if (defStatus.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
defStatus.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
logger.debug("Initiating transaction rollback");
doRollback(defStatus);
}
else if (defStatus.getTransaction() != null) {
if (defStatus.isDebug()) {
logger.debug("Setting existing transaction rollback-only");
}
doSetRollbackOnly(defStatus);
}
else {
logger.warn("Should roll back transaction but cannot - no transaction available");
}
}
catch (RuntimeException ex) {
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, ex);
throw ex;
}
catch (Error err) {
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_UNKNOWN, err);
throw err;
}
triggerAfterCompletion(defStatus, TransactionSynchronization.STATUS_ROLLED_BACK, null);
}
finally {
cleanupAfterCompletion(defStatus);
}
}
/**
* Invoke doRollback, handling rollback exceptions properly.
* @param status object representing the transaction
* @param ex the thrown application exception or error
* @throws TransactionException in case of a rollback error
* @see #doRollback
*/
private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex)
throws TransactionException {
try {
if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback on commit exception", ex);
}
doRollback(status);
}
}
catch (RuntimeException rbex) {
logger.error("Commit exception overridden by rollback exception", ex);
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN, rbex);
throw rbex;
}
catch (Error rberr) {
logger.error("Commit exception overridden by rollback exception", ex);
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN, rberr);
throw rberr;
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK, ex);
}
/**
* Trigger beforeCommit callback.
* @param status object representing the transaction
*/
private void triggerBeforeCommit(DefaultTransactionStatus status) {
if (status.isNewSynchronization()) {
logger.debug("Triggering beforeCommit synchronization");
for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
synchronization.beforeCommit(status.isReadOnly());
}
}
}
/**
* Trigger beforeCompletion callback.
* @param status object representing the transaction
* @param ex the thrown application exception or error, or null
*/
private void triggerBeforeCompletion(DefaultTransactionStatus status, Throwable ex) {
if (status.isNewSynchronization()) {
logger.debug("Triggering beforeCompletion synchronization");
try {
for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
synchronization.beforeCompletion();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -