📄 jtatransactionmanager.java
字号:
* Get a JTA transaction object for the given current UserTransaction.
* <p>Subclasses can override this to provide a JtaTransactionObject
* subclass, for example holding some additional JTA handle needed.
* @param ut the UserTransaction handle to use for the current transaction
* @return the JtaTransactionObject holding the UserTransaction
*/
protected JtaTransactionObject doGetJtaTransaction(UserTransaction ut) {
return new JtaTransactionObject(ut);
}
protected boolean isExistingTransaction(Object transaction) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
return (txObject.getUserTransaction().getStatus() != Status.STATUS_NO_TRANSACTION);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on getStatus", ex);
}
}
/**
* This implementation returns false to cause a further invocation
* of doBegin despite an already existing transaction.
* <p>JTA implementations might support nested transactions via further
* <code>UserTransaction.begin()</code> invocations, but never support savepoints.
* @see #doBegin
* @see javax.transaction.UserTransaction#begin()
*/
protected boolean useSavepointForNestedTransaction() {
return false;
}
protected void doBegin(Object transaction, TransactionDefinition definition) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
doJtaBegin(txObject, definition);
}
catch (NotSupportedException ex) {
// assume nested transaction not supported
throw new NestedTransactionNotSupportedException(
"JTA implementation does not support nested transactions", ex);
}
catch (UnsupportedOperationException ex) {
// assume nested transaction not supported
throw new NestedTransactionNotSupportedException(
"JTA implementation does not support nested transactions", ex);
}
catch (SystemException ex) {
throw new CannotCreateTransactionException("JTA failure on begin", ex);
}
}
/**
* Perform a JTA begin on the JTA UserTransaction or TransactionManager.
* <p>This implementation only supports standard JTA functionality:
* that is, no per-transaction isolation levels and no transaction names.
* Can be overridden in subclasses, for specific JTA implementations.
* <p>Calls <code>applyIsolationLevel</code> and <code>applyTimeout</code>
* before invoking the UserTransaction's <code>begin</code> method.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param definition TransactionDefinition instance, describing propagation
* behavior, isolation level, read-only flag, timeout, and transaction name
* @throws NotSupportedException if thrown by JTA methods
* @throws SystemException if thrown by JTA methods
* @see #getUserTransaction
* @see #getTransactionManager
* @see #applyIsolationLevel
* @see #applyTimeout
* @see JtaTransactionObject#getUserTransaction()
* @see javax.transaction.UserTransaction#setTransactionTimeout
* @see javax.transaction.UserTransaction#begin
*/
protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
throws NotSupportedException, SystemException {
applyIsolationLevel(txObject, definition.getIsolationLevel());
int timeout = determineTimeout(definition);
applyTimeout(txObject, timeout);
txObject.getUserTransaction().begin();
}
/**
* Apply the given transaction isolation level. The default implementation
* will throw an exception for any level other than ISOLATION_DEFAULT.
* <p>To be overridden in subclasses for specific JTA implementations,
* as alternative to overriding the full {@link #doJtaBegin} method.
* @param txObject the JtaTransactionObject containing the UserTransaction
* @param isolationLevel isolation level taken from transaction definition
* @throws InvalidIsolationLevelException if the given isolation level
* cannot be applied
* @throws SystemException if thrown by the JTA implementation
* @see #doJtaBegin
* @see JtaTransactionObject#getUserTransaction()
* @see #getTransactionManager()
*/
protected void applyIsolationLevel(JtaTransactionObject txObject, int isolationLevel)
throws InvalidIsolationLevelException, SystemException {
if (!this.allowCustomIsolationLevels && isolationLevel != TransactionDefinition.ISOLATION_DEFAULT) {
throw new InvalidIsolationLevelException(
"JtaTransactionManager does not support custom isolation levels by default - " +
"switch 'allowCustomIsolationLevels' to 'true'");
}
}
/**
* 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 (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 {
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 (SystemException ex) {
throw new TransactionSystemException("JTA failure on commit", ex);
}
}
protected void doRollback(DefaultTransactionStatus status) {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
if (txObject.getUserTransaction().getStatus() != Status.STATUS_NO_TRANSACTION) {
txObject.getUserTransaction().rollback();
}
}
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 {
if (txObject.getUserTransaction().getStatus() != Status.STATUS_NO_TRANSACTION) {
txObject.getUserTransaction().setRollbackOnly();
}
}
catch (IllegalStateException ex) {
throw new NoTransactionException("No active JTA transaction");
}
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 rollback-only: " +
"cannot register Spring after-completion callbacks with outer JTA transaction - " +
"immediately performing Spring after-completion callbacks with outcome status 'rollback'");
invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_ROLLED_BACK);
}
catch (IllegalStateException ex) {
throw new NoTransactionException("No active JTA transaction");
}
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>Can be overridden in subclasses, for specific JTA implementations.
* @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 #invokeAfterCompletion(java.util.List, int)
*/
protected void doRegisterAfterCompletionWithJtaTransaction(
JtaTransactionObject txObject, List synchronizations)
throws RollbackException, SystemException {
if (getTransactionManager() != null) {
Transaction transaction = getTransactionManager().getTransaction();
if (transaction != null) {
transaction.registerSynchronization(new JtaAfterCompletionSynchronization(synchronizations));
}
else {
// No current JTA Transaction available.
logger.debug("Participating in existing JTA transaction, but no current JTA Transaction 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);
}
}
else {
// No JTA TransactionManager available.
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);
}
}
//---------------------------------------------------------------------
// 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 lookup for JTA UserTransaction and TransactionManager.
initUserTransactionAndTransactionManager();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -