jtatransactionmanager.java
来自「spring framework 2.5.4源代码」· Java 代码 · 共 1,215 行 · 第 1/4 页
JAVA
1,215 行
/**
* Apply the given transaction timeout. The default implementation will call
* <code>UserTransaction.setTransactionTimeout</code> for a non-default timeout value.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param timeout timeout value taken from transaction definition
* @throws SystemException if thrown by the JTA implementation
* @see #doJtaBegin
* @see JtaTransactionObject#getUserTransaction()
* @see javax.transaction.UserTransaction#setTransactionTimeout(int)
*/
protected void applyTimeout(JtaTransactionObject txObject, int timeout) throws SystemException {
if (timeout > TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getUserTransaction().setTransactionTimeout(timeout);
}
}
protected Object doSuspend(Object transaction) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
return doJtaSuspend(txObject);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on suspend", ex);
}
}
/**
* Perform a JTA suspend on the JTA TransactionManager.
* <p>Can be overridden in subclasses, for specific JTA implementations.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @return the suspended JTA Transaction object
* @throws SystemException if thrown by JTA methods
* @see #getTransactionManager()
* @see javax.transaction.TransactionManager#suspend()
*/
protected Object doJtaSuspend(JtaTransactionObject txObject) throws SystemException {
if (getTransactionManager() == null) {
throw new TransactionSuspensionNotSupportedException(
"JtaTransactionManager needs a JTA TransactionManager for suspending a transaction: " +
"specify the 'transactionManager' or 'transactionManagerName' property");
}
return getTransactionManager().suspend();
}
protected void doResume(Object transaction, Object suspendedResources) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
doJtaResume(txObject, suspendedResources);
}
catch (InvalidTransactionException ex) {
throw new IllegalTransactionStateException("Tried to resume invalid JTA transaction", ex);
}
catch (IllegalStateException ex) {
throw new TransactionSystemException("Unexpected internal transaction state", ex);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on resume", ex);
}
}
/**
* Perform a JTA resume on the JTA TransactionManager.
* <p>Can be overridden in subclasses, for specific JTA implementations.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param suspendedTransaction the suspended JTA Transaction object
* @throws InvalidTransactionException if thrown by JTA methods
* @throws SystemException if thrown by JTA methods
* @see #getTransactionManager()
* @see javax.transaction.TransactionManager#resume(javax.transaction.Transaction)
*/
protected void doJtaResume(JtaTransactionObject txObject, Object suspendedTransaction)
throws InvalidTransactionException, SystemException {
if (getTransactionManager() == null) {
throw new TransactionSuspensionNotSupportedException(
"JtaTransactionManager needs a JTA TransactionManager for suspending a transaction: " +
"specify the 'transactionManager' or 'transactionManagerName' property");
}
getTransactionManager().resume((Transaction) suspendedTransaction);
}
/**
* This implementation returns "true": a JTA commit will properly handle
* transactions that have been marked rollback-only at a global level.
*/
protected boolean shouldCommitOnGlobalRollbackOnly() {
return true;
}
protected void doCommit(DefaultTransactionStatus status) {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
int jtaStatus = txObject.getUserTransaction().getStatus();
if (jtaStatus == Status.STATUS_NO_TRANSACTION) {
// Should never happen... would have thrown an exception before
// and as a consequence led to a rollback, not to a commit call.
// In any case, the transaction is already fully cleaned up.
throw new UnexpectedRollbackException("JTA transaction already completed - probably rolled back");
}
if (jtaStatus == Status.STATUS_ROLLEDBACK) {
// Only really happens on JBoss 4.2 in case of an early timeout...
// Explicit rollback call necessary to clean up the transaction.
// IllegalStateException expected on JBoss; call still necessary.
try {
txObject.getUserTransaction().rollback();
}
catch (IllegalStateException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Rollback failure with transaction already marked as rolled back: " + ex);
}
}
throw new UnexpectedRollbackException("JTA transaction already rolled back (probably due to a timeout)");
}
txObject.getUserTransaction().commit();
}
catch (RollbackException ex) {
throw new UnexpectedRollbackException(
"JTA transaction unexpectedly rolled back (maybe due to a timeout)", ex);
}
catch (HeuristicMixedException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_MIXED, ex);
}
catch (HeuristicRollbackException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_ROLLED_BACK, ex);
}
catch (IllegalStateException ex) {
throw new TransactionSystemException("Unexpected internal transaction state", ex);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on commit", ex);
}
}
protected void doRollback(DefaultTransactionStatus status) {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
int jtaStatus = txObject.getUserTransaction().getStatus();
if (jtaStatus != Status.STATUS_NO_TRANSACTION) {
try {
txObject.getUserTransaction().rollback();
}
catch (IllegalStateException ex) {
if (jtaStatus == Status.STATUS_ROLLEDBACK) {
// Only really happens on JBoss 4.2 in case of an early timeout...
if (logger.isDebugEnabled()) {
logger.debug("Rollback failure with transaction already marked as rolled back: " + ex);
}
}
else {
throw new TransactionSystemException("Unexpected internal transaction state", ex);
}
}
}
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on rollback", ex);
}
}
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting JTA transaction rollback-only");
}
try {
int jtaStatus = txObject.getUserTransaction().getStatus();
if (jtaStatus != Status.STATUS_NO_TRANSACTION && jtaStatus != Status.STATUS_ROLLEDBACK) {
txObject.getUserTransaction().setRollbackOnly();
}
}
catch (IllegalStateException ex) {
throw new TransactionSystemException("Unexpected internal transaction state", ex);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on setRollbackOnly", ex);
}
}
protected void registerAfterCompletionWithExistingTransaction(Object transaction, List synchronizations) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
logger.debug("Registering after-completion synchronization with existing JTA transaction");
try {
doRegisterAfterCompletionWithJtaTransaction(txObject, synchronizations);
}
catch (RollbackException ex) {
logger.debug("Participating in existing JTA transaction that has been marked for rollback: " +
"cannot register Spring after-completion callbacks with outer JTA transaction - " +
"immediately performing Spring after-completion callbacks with outcome status 'rollback'. " +
"Original exception: " + ex);
invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_ROLLED_BACK);
}
catch (IllegalStateException ex) {
logger.debug("Participating in existing JTA transaction, but unexpected internal transaction " +
"state encountered: cannot register Spring after-completion callbacks with outer JTA " +
"transaction - processing Spring after-completion callbacks with outcome status 'unknown'" +
"Original exception: " + ex);
invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_UNKNOWN);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on registerSynchronization", ex);
}
}
/**
* Register a JTA synchronization on the JTA TransactionManager, for calling
* <code>afterCompletion</code> on the given Spring TransactionSynchronizations.
* <p>The default implementation registers the synchronizations on the
* JTA 1.1 TransactionSynchronizationRegistry, if available, or on the
* JTA TransactionManager's current Transaction - again, if available.
* If none of the two is available, a warning will be logged.
* <p>Can be overridden in subclasses, for specific JTA implementations.
* @param txObject the current transaction object
* @param synchronizations List of TransactionSynchronization objects
* @throws RollbackException if thrown by JTA methods
* @throws SystemException if thrown by JTA methods
* @see #getTransactionManager()
* @see javax.transaction.Transaction#registerSynchronization
* @see javax.transaction.TransactionSynchronizationRegistry#registerInterposedSynchronization
*/
protected void doRegisterAfterCompletionWithJtaTransaction(JtaTransactionObject txObject, List synchronizations)
throws RollbackException, SystemException {
int jtaStatus = txObject.getUserTransaction().getStatus();
if (jtaStatus == Status.STATUS_NO_TRANSACTION) {
throw new RollbackException("JTA transaction already completed - probably rolled back");
}
if (jtaStatus == Status.STATUS_ROLLEDBACK) {
throw new RollbackException("JTA transaction already rolled back (probably due to a timeout)");
}
if (this.transactionSynchronizationRegistry != null) {
// JTA 1.1 TransactionSynchronizationRegistry available - use it.
new InterposedSynchronizationDelegate().registerInterposedSynchronization(
new JtaAfterCompletionSynchronization(synchronizations));
}
else if (getTransactionManager() != null) {
// At least the JTA TransactionManager available - use that one.
Transaction transaction = getTransactionManager().getTransaction();
if (transaction == null) {
throw new IllegalStateException("No JTA Transaction available");
}
transaction.registerSynchronization(new JtaAfterCompletionSynchronization(synchronizations));
}
else {
// No JTA TransactionManager available - log a warning.
logger.warn("Participating in existing JTA transaction, but no JTA TransactionManager available: " +
"cannot register Spring after-completion callbacks with outer JTA transaction - " +
"processing Spring after-completion callbacks with outcome status 'unknown'");
invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_UNKNOWN);
}
}
//---------------------------------------------------------------------
// Implementation of TransactionFactory interface
//---------------------------------------------------------------------
public Transaction createTransaction(String name, int timeout) throws NotSupportedException, SystemException {
TransactionManager tm = getTransactionManager();
Assert.state(tm != null, "No JTA TransactionManager available");
if (timeout >= 0) {
tm.setTransactionTimeout(timeout);
}
tm.begin();
return tm.getTransaction();
}
//---------------------------------------------------------------------
// Serialization support
//---------------------------------------------------------------------
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// Rely on default serialization; just initialize state after deserialization.
ois.defaultReadObject();
// Create template for client-side JNDI lookup.
this.jndiTemplate = new JndiTemplate();
// Perform a fresh lookup for JTA handles.
initUserTransactionAndTransactionManager();
initTransactionSynchronizationRegistry();
}
/**
* Inner class to avoid a direct dependency on the JTA 1.1 API
* (javax.transaction.TransactionSynchronizationRegistry interface).
*/
private class InterposedSynchronizationDelegate {
public void registerInterposedSynchronization(Synchronization synch) {
((TransactionSynchronizationRegistry) transactionSynchronizationRegistry).registerInterposedSynchronization(synch);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?