📄 jtatransactionmanager.java
字号:
* for every transaction. This is only necessary for application servers
* that return a new UserTransaction for every transaction, keeping state
* tied to the UserTransaction object itself rather than the current thread.
* @see #setUserTransactionName
*/
public void setCacheUserTransaction(boolean cacheUserTransaction) {
this.cacheUserTransaction = cacheUserTransaction;
}
/**
* Set the JTA TransactionManager to use as direct reference.
* <p>A TransactionManager is necessary for suspending and resuming transactions,
* as this not supported by the UserTransaction interface.
* <p>Note that the TransactionManager will be autodetected if the JTA
* UserTransaction object implements the JTA TransactionManager interface too,
* as well as autodetected at various well-known fallback JNDI locations.
* @see #setTransactionManagerName
* @see #setAutodetectTransactionManager
*/
public void setTransactionManager(TransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* Return the JTA TransactionManager that this transaction manager uses.
*/
public TransactionManager getTransactionManager() {
return this.transactionManager;
}
/**
* Set the JNDI name of the JTA TransactionManager.
* <p>A TransactionManager is necessary for suspending and resuming transactions,
* as this not supported by the UserTransaction interface.
* <p>Note that the TransactionManager will be autodetected if the JTA
* UserTransaction object implements the JTA TransactionManager interface too,
* as well as autodetected at various well-known fallback JNDI locations.
* @see #setTransactionManager
* @see #setAutodetectTransactionManager
*/
public void setTransactionManagerName(String transactionManagerName) {
this.transactionManagerName = transactionManagerName;
}
/**
* Set whether to autodetect a JTA UserTransaction object that implements
* the JTA TransactionManager interface too (i.e. the JNDI location for the
* TransactionManager is "java:comp/UserTransaction", same as for the UserTransaction).
* Also checks the fallback JNDI locations "java:comp/TransactionManager" and
* "java:/TransactionManager". Will proceed without TransactionManager if none found.
* <p>Default is "true", autodetecting the TransactionManager unless it has been
* specified explicitly. 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 fast.
* @see #FALLBACK_TRANSACTION_MANAGER_NAMES
*/
public void setAutodetectTransactionManager(boolean autodetectTransactionManager) {
this.autodetectTransactionManager = autodetectTransactionManager;
}
public void afterPropertiesSet() throws TransactionSystemException {
// Fetch JTA UserTransaction from JNDI, if necessary.
if (this.userTransaction == null) {
if (this.userTransactionName != null) {
this.userTransaction = lookupUserTransaction(this.userTransactionName);
}
else {
this.userTransaction = retrieveUserTransaction();
}
}
// Fetch JTA TransactionManager from JNDI, if necessary.
if (this.transactionManager == null) {
if (this.transactionManagerName != null) {
this.transactionManager = lookupTransactionManager(this.transactionManagerName);
}
else {
this.transactionManager = retrieveTransactionManager();
}
}
// Autodetect UserTransaction object that implements TransactionManager,
// and check fallback JNDI locations else.
if (this.transactionManager == null && this.autodetectTransactionManager) {
this.transactionManager = findTransactionManager(this.userTransaction);
}
// If only JTA TransactionManager specified, create UserTransaction handle for it.
if (this.userTransaction == null && this.transactionManager != null) {
if (this.transactionManager instanceof UserTransaction) {
this.userTransaction = (UserTransaction) this.transactionManager;
}
else {
this.userTransaction = new UserTransactionAdapter(this.transactionManager);
}
}
// We at least need the JTA UserTransaction.
if (this.userTransaction != null) {
if (logger.isInfoEnabled()) {
logger.info("Using JTA UserTransaction: " + this.userTransaction);
}
}
else {
throw new IllegalArgumentException(
"Either 'userTransaction' or 'userTransactionName' or 'transactionManager' " +
"or 'transactionManagerName' must be specified");
}
// For transaction suspension, the JTA TransactionManager is necessary too.
if (this.transactionManager != null) {
if (logger.isInfoEnabled()) {
logger.info("Using JTA TransactionManager: " + this.transactionManager);
}
}
else {
logger.warn("No JTA TransactionManager found: " +
"transaction suspension and synchronization with existing JTA transactions not available");
}
}
/**
* Look up the JTA UserTransaction in JNDI via the configured name.
* Called by <code>afterPropertiesSet</code> 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 {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving JTA UserTransaction from JNDI location [" + userTransactionName + "]");
}
return (UserTransaction) getJndiTemplate().lookup(userTransactionName, UserTransaction.class);
}
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 <code>afterPropertiesSet</code> 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 {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving JTA TransactionManager from JNDI location [" + transactionManagerName + "]");
}
return (TransactionManager) getJndiTemplate().lookup(transactionManagerName, TransactionManager.class);
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA TransactionManager is not available at JNDI location [" + transactionManagerName + "]", ex);
}
}
/**
* Allows subclasses to retrieve the JTA UserTransaction in a vendor-specific manner.
* Only called if no "userTransaction" or "userTransactionName" specified.
* <p>The default implementation simply returns <code>null</code>.
* @return the JTA UserTransaction handle to use, or <code>null</code> if none found
* @throws TransactionSystemException in case of errors
* @see #setUserTransaction
* @see #setUserTransactionName
*/
protected UserTransaction retrieveUserTransaction() throws TransactionSystemException {
return null;
}
/**
* Allows subclasses to retrieve the JTA TransactionManager in a vendor-specific manner.
* Only called if no "transactionManager" or "transactionManagerName" specified.
* <p>The default implementation simply returns <code>null</code>.
* @return the JTA TransactionManager handle to use, or <code>null</code> if none found
* @throws TransactionSystemException in case of errors
* @see #setTransactionManager
* @see #setTransactionManagerName
*/
protected TransactionManager retrieveTransactionManager() throws TransactionSystemException {
return null;
}
/**
* Find the JTA TransactionManager through autodetection:
* checking whether the UserTransaction object implements the
* TransactionManager, and checking the fallback JNDI locations.
* @param ut the JTA UserTransaction object
* @return the JTA TransactionManager reference, or <code>null</code> if not found
* @see #FALLBACK_TRANSACTION_MANAGER_NAMES
*/
protected TransactionManager findTransactionManager(UserTransaction ut) {
if (ut instanceof TransactionManager) {
if (logger.isDebugEnabled()) {
logger.debug("JTA UserTransaction object [" + ut + "] implements TransactionManager");
}
return (TransactionManager) ut;
}
// Check fallback JNDI locations.
for (int i = 0; i < FALLBACK_TRANSACTION_MANAGER_NAMES.length; i++) {
String jndiName = FALLBACK_TRANSACTION_MANAGER_NAMES[i];
try {
TransactionManager tm = lookupTransactionManager(jndiName);
if (logger.isDebugEnabled()) {
logger.debug("JTA TransactionManager found at fallback JNDI location [" + jndiName + "]");
}
return tm;
}
catch (TransactionSystemException ex) {
if (logger.isDebugEnabled()) {
logger.debug("No JTA TransactionManager found at fallback JNDI location [" + jndiName + "]", ex);
}
}
}
// OK, so no JTA TransactionManager is available...
return null;
}
/**
* This implementation returns a JtaTransactionObject instance for the
* JTA UserTransaction.
* <p>The UserTransaction object will either be looked up freshly for the
* current transaction, or the cached one looked up at startup will be used.
* The latter is the default: Most application servers use a shared singleton
* UserTransaction that can be cached. Turn off the "cacheUserTransaction"
* flag to enforce a fresh lookup for every transaction.
* @see #setCacheUserTransaction
*/
protected Object doGetTransaction() {
UserTransaction ut = getUserTransaction();
if (!this.cacheUserTransaction && this.userTransactionName != null) {
ut = lookupUserTransaction(this.userTransactionName);
}
return doGetJtaTransaction(ut);
}
/**
* 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);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -