📄 jtatransactionmanager.java
字号:
/**
* Return the JTA TransactionManager that this transaction manager uses.
*/
public TransactionManager getTransactionManager() {
return transactionManager;
}
/**
* Set whether to autodetect a JTA UserTransaction object that implements the
* JTA TransactionManager interface too. Default is true.
* <p>Can be turned off to deliberately ignore an available TransactionManager,
* for example when there are known issues with suspend/resume and any attempt
* to use REQUIRES_NEW or NOT_SUPPORTED should fail.
*/
public void setAutodetectTransactionManager(boolean autodetectTransactionManager) {
this.autodetectTransactionManager = autodetectTransactionManager;
}
public void afterPropertiesSet() throws TransactionSystemException {
if (this.userTransaction == null) {
if (this.userTransactionName != null) {
this.userTransaction = lookupUserTransaction(this.userTransactionName);
}
else if (this.transactionManager instanceof UserTransaction) {
this.userTransaction = (UserTransaction) this.transactionManager;
}
else if (this.transactionManager != null) {
this.userTransaction = new UserTransactionAdapter(this.transactionManager);
}
else {
throw new IllegalArgumentException(
"Either userTransaction or userTransactionName or transactionManager must be set");
}
}
if (this.transactionManager == null) {
if (this.transactionManagerName != null) {
this.transactionManager = lookupTransactionManager(this.transactionManagerName);
}
else if (this.autodetectTransactionManager && this.userTransaction instanceof TransactionManager) {
if (logger.isInfoEnabled()) {
logger.info("JTA UserTransaction object [" + this.userTransaction + "] implements TransactionManager");
}
this.transactionManager = (TransactionManager) this.userTransaction;
}
else {
logger.info("No JTA TransactionManager specified: transaction suspension not available");
}
}
}
/**
* Look up the JTA UserTransaction in JNDI via the configured name.
* Called by afterPropertiesSet if no direct UserTransaction reference was set.
* Can be overridden in subclasses to provide a different UserTransaction object.
* @param userTransactionName the JNDI name of the UserTransaction
* @return the UserTransaction object
* @throws TransactionSystemException if the JNDI lookup failed
* @see #setJndiTemplate
* @see #setUserTransactionName
*/
protected UserTransaction lookupUserTransaction(String userTransactionName)
throws TransactionSystemException {
try {
UserTransaction ut = (UserTransaction)
getJndiTemplate().lookup(userTransactionName, UserTransaction.class);
if (logger.isInfoEnabled()) {
logger.info("Using JTA UserTransaction [" + ut + "] from JNDI location [" + userTransactionName + "]");
}
return ut;
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA UserTransaction is not available at JNDI location [" + userTransactionName + "]", ex);
}
}
/**
* Look up the JTA TransactionManager in JNDI via the configured name.
* Called by afterPropertiesSet if no direct TransactionManager reference was set.
* Can be overridden in subclasses to provide a different TransactionManager object.
* @param transactionManagerName the JNDI name of the TransactionManager
* @return the UserTransaction object
* @throws TransactionSystemException if the JNDI lookup failed
* @see #setJndiTemplate
* @see #setTransactionManagerName
*/
protected TransactionManager lookupTransactionManager(String transactionManagerName)
throws TransactionSystemException {
try {
TransactionManager tm = (TransactionManager)
getJndiTemplate().lookup(transactionManagerName, TransactionManager.class);
if (logger.isInfoEnabled()) {
logger.info("Using JTA TransactionManager [" + tm + "] from JNDI location [" +
transactionManagerName + "]");
}
return tm;
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA TransactionManager is not available at JNDI location [" + transactionManagerName + "]", ex);
}
}
/**
* This implementation returns a JtaTransactionObject instance for the
* JTA UserTransaction.
* <p>Note that JtaTransactionManager doesn't need a transaction object,
* as it will access the JTA UserTransaction and/or TransactionManager
* singletons that it holds directly. Therefore, any transaction object
* that's useful for status and identification purposes will do.
*/
protected Object doGetTransaction() {
return new JtaTransactionObject(getUserTransaction());
}
protected boolean isExistingTransaction(Object transaction) {
try {
return (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) {
logger.debug("Beginning JTA transaction");
try {
applyIsolationLevel(definition.getIsolationLevel());
if (definition.getTimeout() > TransactionDefinition.TIMEOUT_DEFAULT) {
getUserTransaction().setTransactionTimeout(definition.getTimeout());
}
getUserTransaction().begin();
}
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);
}
}
/**
* Apply the given transaction isolation level. Default implementation
* will throw an exception for any level other than ISOLATION_DEFAULT.
* To be overridden in subclasses for specific JTA implementations.
* @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 #getUserTransaction
* @see #getTransactionManager
*/
protected void applyIsolationLevel(int isolationLevel)
throws InvalidIsolationLevelException, SystemException {
if (isolationLevel != TransactionDefinition.ISOLATION_DEFAULT) {
throw new InvalidIsolationLevelException(
"JtaTransactionManager does not support custom isolation levels");
}
}
protected Object doSuspend(Object transaction) {
if (getTransactionManager() == null) {
throw new TransactionSuspensionNotSupportedException(
"JtaTransactionManager needs a JTA TransactionManager for suspending a transaction - " +
"specify the 'transactionManager' or 'transactionManagerName' property");
}
try {
return doJtaSuspend();
}
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.
* @return the suspended JTA Transaction object
* @throws SystemException if thrown by JTA methods
* @see #getTransactionManager
*/
protected Transaction doJtaSuspend() throws SystemException {
return getTransactionManager().suspend();
}
protected void doResume(Object transaction, Object suspendedResources) {
if (getTransactionManager() == null) {
throw new TransactionSuspensionNotSupportedException(
"JtaTransactionManager needs a JTA TransactionManager for suspending a transaction - " +
"specify the 'transactionManager' or 'transactionManagerName' property");
}
try {
doJtaResume((Transaction) 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 suspendedTransaction the suspended JTA Transaction object
* @throws InvalidTransactionException if thrown by JTA methods
* @throws SystemException if thrown by JTA methods
* @see #getTransactionManager
*/
protected void doJtaResume(Transaction suspendedTransaction)
throws InvalidTransactionException, SystemException {
getTransactionManager().resume(suspendedTransaction);
}
protected void doCommit(DefaultTransactionStatus status) {
logger.debug("Committing JTA transaction");
try {
getUserTransaction().commit();
}
catch (RollbackException ex) {
throw new UnexpectedRollbackException("JTA transaction rolled back", 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) {
logger.debug("Rolling back JTA transaction");
try {
getUserTransaction().rollback();
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on rollback", ex);
}
}
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
if (status.isDebug()) {
logger.debug("Setting JTA transaction rollback-only");
}
try {
getUserTransaction().setRollbackOnly();
}
catch (IllegalStateException ex) {
throw new NoTransactionException("No active JTA transaction");
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on setRollbackOnly", ex);
}
}
//---------------------------------------------------------------------
// Serialization support
//---------------------------------------------------------------------
private void readObject(ObjectInputStream ois) throws IOException {
// Rely on default serialization, just initialize state after deserialization.
try {
ois.defaultReadObject();
}
catch (ClassNotFoundException ex) {
throw new IOException(
"Failed to deserialize JtaTransactionManager - check that JTA and Spring transaction " +
"libraries are available on the client side: " + ex.getMessage());
}
// do client-side JNDI lookup
this.jndiTemplate = new JndiTemplate();
// run lookup code for UserTransaction
this.userTransaction = lookupUserTransaction(this.userTransactionName);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -