📄 abstractplatformtransactionmanager.java
字号:
// can only be caused by doCommit
if (this.rollbackOnCommitFailure) {
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;
try {
try {
triggerBeforeCompletion(defStatus, null);
if (status.isNewTransaction()) {
logger.info("Initiating transaction rollback");
doRollback(defStatus);
}
else if (defStatus.getTransaction() != null) {
if (defStatus.isDebug()) {
logger.debug("Setting existing transaction rollback-only");
}
doSetRollbackOnly(defStatus);
}
else {
logger.info("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();
}
}
catch (RuntimeException tsex) {
if (ex != null) {
logger.error("Rollback exception overridden by synchronization exception", ex);
}
throw tsex;
}
catch (Error tserr) {
if (ex != null) {
logger.error("Rollback exception overridden by synchronization exception", ex);
}
throw tserr;
}
}
}
/**
* Trigger afterCompletion callback, handling exceptions properly.
* @param status object representing the transaction
* @param completionStatus completion status according to TransactionSynchronization constants
* @param ex the thrown application exception or error, or null
*/
private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus, Throwable ex) {
if (status.isNewSynchronization()) {
logger.debug("Triggering afterCompletion synchronization");
try {
for (Iterator it = TransactionSynchronizationManager.getSynchronizations().iterator(); it.hasNext();) {
TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
synchronization.afterCompletion(completionStatus);
}
}
catch (RuntimeException tsex) {
if (ex != null) {
logger.error("Rollback exception overridden by synchronization exception", ex);
}
throw tsex;
}
catch (Error tserr) {
if (ex != null) {
logger.error("Rollback exception overridden by synchronization exception", ex);
}
throw tserr;
}
}
}
/**
* Clean up after completion, clearing synchronization if necessary,
* and invoking doCleanupAfterCompletion.
* @param status object representing the transaction
* @see #doCleanupAfterCompletion
*/
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.clearSynchronization();
}
if (status.isNewTransaction()) {
doCleanupAfterCompletion(status.getTransaction());
}
if (status.getSuspendedResources() != null) {
if (status.isDebug()) {
logger.debug("Resuming suspended transaction");
}
resume(status.getTransaction(), status.getSuspendedResources());
}
}
/**
* Return a current transaction object, i.e. a JTA UserTransaction.
* @return the current transaction object
* @throws org.springframework.transaction.CannotCreateTransactionException
* if transaction support is not available (e.g. no JTA UserTransaction retrievable from JNDI)
* @throws TransactionException in case of lookup or system errors
*/
protected abstract Object doGetTransaction() throws TransactionException;
/**
* Check if the given transaction object indicates an existing,
* i.e. already begun, transaction.
* @param transaction transaction object returned by doGetTransaction
* @return if there is an existing transaction
* @throws TransactionException in case of system errors
*/
protected abstract boolean isExistingTransaction(Object transaction) throws TransactionException;
/**
* Begin a new transaction with the given transaction definition.
* Does not have to care about applying the propagation behavior,
* as this has already been handled by this abstract manager.
* @param transaction transaction object returned by doGetTransaction
* @param definition TransactionDefinition instance, describing
* propagation behavior, isolation level, timeout etc.
* @throws TransactionException in case of creation or system errors
*/
protected abstract void doBegin(Object transaction, TransactionDefinition definition)
throws TransactionException;
/**
* Suspend the resources of the current transaction.
* Transaction synchronization will already have been suspended.
* @param transaction transaction object returned by doGetTransaction
* @return an object that holds suspended resources
* (will be kept unexamined for passing it into doResume)
* @throws org.springframework.transaction.IllegalTransactionStateException
* if suspending is not supported by the transaction manager implementation
* @throws TransactionException in case of system errors
* @see #doResume
*/
protected abstract Object doSuspend(Object transaction) throws TransactionException;
/**
* Resume the resources of the current transaction.
* Transaction synchronization will be resumed afterwards.
* @param transaction transaction object returned by doGetTransaction
* @param suspendedResources the object that holds suspended resources,
* as returned by doSuspend
* @throws org.springframework.transaction.IllegalTransactionStateException
* if resuming is not supported by the transaction manager implementation
* @throws TransactionException in case of system errors
* @see #doSuspend
*/
protected abstract void doResume(Object transaction, Object suspendedResources)
throws TransactionException;
/**
* Check if the given transaction object indicates a rollback-only,
* assumably from a nested transaction (else, the TransactionStatus
* of this transaction would have indicated rollback-only).
* @param transaction transaction object returned by doGetTransaction
* @return if the transaction has to result in a rollback
* @throws TransactionException in case of creation or system errors
*/
protected abstract boolean isRollbackOnly(Object transaction) throws TransactionException;
/**
* Perform an actual commit on the given transaction.
* An implementation does not need to check the rollback-only flag.
* @param status status representation of the transaction
* @throws TransactionException in case of commit or system errors
*/
protected abstract void doCommit(DefaultTransactionStatus status) throws TransactionException;
/**
* Perform an actual rollback on the given transaction.
* An implementation does not need to check the new transaction flag.
* @param status status representation of the transaction
* @throws TransactionException in case of system errors
*/
protected abstract void doRollback(DefaultTransactionStatus status) throws TransactionException;
/**
* Set the given transaction rollback-only. Only called on rollback
* if the current transaction takes part in an existing one.
* @param status status representation of the transaction
* @throws TransactionException in case of system errors
*/
protected abstract void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException;
/**
* Cleanup resources after transaction completion.
* Called after doCommit and doRollback execution on any outcome.
* Should not throw any exceptions but just issue warnings on errors.
* @param transaction transaction object returned by doGetTransaction
*/
protected abstract void doCleanupAfterCompletion(Object transaction);
/**
* Holder for suspended resources.
* Used internally by suspend and resume.
* @see #suspend
* @see #resume
*/
private static class SuspendedResourcesHolder {
private final List suspendedSynchronizations;
private final Object suspendedResources;
private SuspendedResourcesHolder(List suspendedSynchronizations, Object suspendedResources) {
this.suspendedSynchronizations = suspendedSynchronizations;
this.suspendedResources = suspendedResources;
}
private List getSuspendedSynchronizations() {
return suspendedSynchronizations;
}
private Object getSuspendedResources() {
return suspendedResources;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -