001: //$Id: JTATransactionFactory.java 10339 2006-08-24 15:07:03Z steve.ebersole@jboss.com $
002: package org.hibernate.transaction;
003:
004: import java.util.Properties;
005:
006: import javax.naming.InitialContext;
007: import javax.naming.NamingException;
008: import javax.transaction.SystemException;
009: import javax.transaction.UserTransaction;
010:
011: import org.apache.commons.logging.Log;
012: import org.apache.commons.logging.LogFactory;
013: import org.hibernate.ConnectionReleaseMode;
014: import org.hibernate.HibernateException;
015: import org.hibernate.Transaction;
016: import org.hibernate.TransactionException;
017: import org.hibernate.jdbc.JDBCContext;
018: import org.hibernate.cfg.Environment;
019: import org.hibernate.util.NamingHelper;
020: import org.hibernate.util.JTAHelper;
021:
022: /**
023: * Factory for <tt>JTATransaction</tt>.
024: *
025: * @see JTATransaction
026: * @author Gavin King
027: */
028: public class JTATransactionFactory implements TransactionFactory {
029:
030: private static final Log log = LogFactory
031: .getLog(JTATransactionFactory.class);
032: private static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
033:
034: protected InitialContext context;
035: protected String utName;
036:
037: public void configure(Properties props) throws HibernateException {
038: try {
039: context = NamingHelper.getInitialContext(props);
040: } catch (NamingException ne) {
041: log.error("Could not obtain initial context", ne);
042: throw new HibernateException(
043: "Could not obtain initial context", ne);
044: }
045:
046: utName = props.getProperty(Environment.USER_TRANSACTION);
047:
048: if (utName == null) {
049: TransactionManagerLookup lookup = TransactionManagerLookupFactory
050: .getTransactionManagerLookup(props);
051: if (lookup != null)
052: utName = lookup.getUserTransactionName();
053: }
054:
055: if (utName == null)
056: utName = DEFAULT_USER_TRANSACTION_NAME;
057: }
058:
059: public Transaction createTransaction(JDBCContext jdbcContext,
060: Context transactionContext) throws HibernateException {
061: return new JTATransaction(context, utName, jdbcContext,
062: transactionContext);
063: }
064:
065: public ConnectionReleaseMode getDefaultReleaseMode() {
066: return ConnectionReleaseMode.AFTER_STATEMENT;
067: }
068:
069: public boolean isTransactionManagerRequired() {
070: return false;
071: }
072:
073: public boolean areCallbacksLocalToHibernateTransactions() {
074: return false;
075: }
076:
077: public boolean isTransactionInProgress(JDBCContext jdbcContext,
078: Context transactionContext, Transaction transaction) {
079: try {
080: // Essentially:
081: // 1) If we have a local (Hibernate) transaction in progress
082: // and it already has the UserTransaction cached, use that
083: // UserTransaction to determine the status.
084: // 2) If a transaction manager has been located, use
085: // that transaction manager to determine the status.
086: // 3) Finally, as the last resort, try to lookup the
087: // UserTransaction via JNDI and use that to determine the
088: // status.
089: if (transaction != null) {
090: UserTransaction ut = ((JTATransaction) transaction)
091: .getUserTransaction();
092: if (ut != null) {
093: return JTAHelper.isInProgress(ut.getStatus());
094: }
095: }
096:
097: if (jdbcContext.getFactory().getTransactionManager() != null) {
098: return JTAHelper.isInProgress(jdbcContext.getFactory()
099: .getTransactionManager().getStatus());
100: } else {
101: try {
102: UserTransaction ut = (UserTransaction) context
103: .lookup(utName);
104: return ut != null
105: && JTAHelper.isInProgress(ut.getStatus());
106: } catch (NamingException ne) {
107: throw new TransactionException(
108: "Unable to locate UserTransaction to check status",
109: ne);
110: }
111: }
112: } catch (SystemException se) {
113: throw new TransactionException(
114: "Unable to check transaction status", se);
115: }
116: }
117:
118: }
|