Java Mailing List Archive

http://www.gg3721.com/

Home » Hibernate Commits List »

[hibernate-commits] Hibernate SVN: r14893 -
 core/branches/Branch_3_2/src/org/hibernate/transaction.

hibernate-commits

2008-07-08


Author LoginPost Reply
Author: steve.ebersole@(protected)
Date: 2008-07-08 11:36:59 -0400 (Tue, 08 Jul 2008)
New Revision: 14893

Modified:
 core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransaction.java
 core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransactionFactory.java
Log:
HHH-3358 : better non-JNDI distributed transaction support

Modified: core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransaction.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransaction.java  2008-07-08 13:08:34 UTC (rev 14892)
+++ core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransaction.java  2008-07-08 15:36:59 UTC (rev 14893)
@@(protected) @@
-//$Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
package org.hibernate.transaction;

-import javax.naming.InitialContext;
-import javax.naming.NamingException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
@@(protected) @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.hibernate.AssertionFailure;
+
import org.hibernate.HibernateException;
import org.hibernate.Transaction;
import org.hibernate.TransactionException;
@@(protected) @@
import org.hibernate.util.JTAHelper;

/**
- * Implements a basic transaction strategy for JTA transactions. Instances check to
- * see if there is an existing JTA transaction. If none exists, a new transaction
- * is started. If one exists, all work is done in the existing context. The
- * following properties are used to locate the underlying <tt>UserTransaction</tt>:
- * <br><br>
- * <table>
- * <tr><td><tt>hibernate.jndi.url</tt></td><td>JNDI initial context URL</td></tr>
- * <tr><td><tt>hibernate.jndi.class</tt></td><td>JNDI provider class</td></tr>
- * <tr><td><tt>jta.UserTransaction</tt></td><td>JNDI name</td></tr>
- * </table>
+ * {@(protected)
+ * a JTA {@(protected)
+ * here we are actually managing the transactions through the Hibernate
+ * transaction mechanism.
+ *
* @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
*/
public class JTATransaction implements Transaction {

@@(protected) @@
 private final JDBCContext jdbcContext;
 private final TransactionFactory.Context transactionContext;

-  private UserTransaction ut;
+  private UserTransaction userTransaction;
 private boolean newTransaction;
 private boolean begun;
 private boolean commitFailed;
 private boolean commitSucceeded;
 private boolean callback;
-  
-  public JTATransaction(
-      InitialContext context,
-      String utName,
-      JDBCContext jdbcContext,
-      TransactionFactory.Context transactionContext
-  ) {
+
+   public JTATransaction(
+      UserTransaction userTransaction,
+      JDBCContext jdbcContext,
+      TransactionFactory.Context transactionContext) {
   this.jdbcContext = jdbcContext;
   this.transactionContext = transactionContext;
-
-    log.debug("Looking for UserTransaction under: " + utName);
-    
-    try {
-      ut = (UserTransaction) context.lookup(utName);
-    }
-    catch (NamingException ne) {
-      log.error("Could not find UserTransaction in JNDI", ne);
-      throw new TransactionException("Could not find UserTransaction in JNDI: ", ne);
-    }
-    if (ut==null) {
-      throw new AssertionFailure("A naming service lookup returned null");
-    }
-
-    log.debug("Obtained UserTransaction");
+     this.userTransaction = userTransaction;
 }

 public void begin() throws HibernateException {
@@(protected) @@
   log.debug("begin");

   try {
-      newTransaction = ut.getStatus() == Status.STATUS_NO_TRANSACTION;
+      newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
     if (newTransaction) {
-        ut.begin();
+        userTransaction.begin();
       log.debug("Began a new JTA transaction");
     }
   }
@@(protected) @@

   if (newTransaction) {
     try {
-        ut.commit();
+        userTransaction.commit();
       commitSucceeded = true;
       log.debug("Committed JTA UserTransaction");
     }
@@(protected) @@
   try {
     if (newTransaction) {
       if (!commitFailed) {
-          ut.rollback();
+          userTransaction.rollback();
         log.debug("Rolled back JTA UserTransaction");
       }
     }
     else {
-        ut.setRollbackOnly();
+        userTransaction.setRollbackOnly();
       log.debug("set JTA UserTransaction to rollback only");
     }
   }
@@(protected) @@
     }
     int status=NULL;
     try {
-        status = ut.getStatus();
+        status = userTransaction.getStatus();
     }
     catch (Exception e) {
       log.error("Could not determine transaction status after commit", e);
@@(protected) @@

   final int status;
   try {
-      status = ut.getStatus();
+      status = userTransaction.getStatus();
   }
   catch (SystemException se) {
     log.error("Could not determine transaction status", se);
@@(protected) @@

   final int status;
   try {
-      status = ut.getStatus();
+      status = userTransaction.getStatus();
   }
   catch (SystemException se) {
     log.error("Could not determine transaction status", se);
@@(protected) @@

   final int status;
   try {
-      status = ut.getStatus();
+      status = userTransaction.getStatus();
   }
   catch (SystemException se) {
     log.error("Could not determine transaction status", se);
@@(protected) @@

 public void setTimeout(int seconds) {
   try {
-      ut.setTransactionTimeout(seconds);
+      userTransaction.setTransactionTimeout(seconds);
   }
   catch (SystemException se) {
     throw new TransactionException("could not set transaction timeout", se);
@@(protected) @@
 }

 protected UserTransaction getUserTransaction() {
-    return ut;
+    return userTransaction;
 }
}

Modified: core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransactionFactory.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransactionFactory.java  2008-07-08 13:08:34 UTC (rev 14892)
+++ core/branches/Branch_3_2/src/org/hibernate/transaction/JTATransactionFactory.java  2008-07-08 15:36:59 UTC (rev 14893)
@@(protected) @@
-//$Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
package org.hibernate.transaction;

import java.util.Properties;
@@(protected) @@
import org.hibernate.util.JTAHelper;

/**
- * Factory for <tt>JTATransaction</tt>.
+ * Factory for {@(protected).
+ * <p/>
+ * To be completely accurate to the JTA spec, JTA implementations should
+ * publish their contextual {@(protected).
+ * However, in practice there are quite a few <tt>stand-alone</tt>
+ * implementations intended for use outside of J2EE/JEE containers and
+ * which therefore do not publish their {@(protected)
+ * into JNDI but which otherwise follow the aspects of the JTA specification.
+ * This {@(protected).
+ * <p/>
+ * For complete JTA implementations (including dependence on JNDI), the
+ * {@(protected)
+ * {@(protected)
+ * {@(protected)
+ * {@(protected)
+ * {@(protected)}.
+ * <p/>
+ * For the so-called <tt>stand-alone</tt> implementations, we do not care at
+ * all about the JNDI aspects just described. Here, the implementation would
+ * have a specific manner to obtain a reference to its contextual
+ * {@(protected)
+ * again it varies. Anyway, for each implementation the integration would need
+ * to override the {@(protected)
+ * thing.
*
- * @see JTATransaction
* @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
*/
public class JTATransactionFactory implements TransactionFactory {
-
+  public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
 private static final Log log = LogFactory.getLog(JTATransactionFactory.class);
-  private static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";

-  protected InitialContext context;
-  protected String utName;
+  protected InitialContext initialContext;
+  protected String userTransactionName;

+  /**
+   * Configure this transaction factory. Specifically here we are attempting to
+   * resolve both an {@(protected)
+   * {@(protected)}.
+   *
+   * @param props The configuration properties
+   *
+   * @exception HibernateException
+   */
 public void configure(Properties props) throws HibernateException {
+    this.initialContext = resolveInitialContext( props );
+    this.userTransactionName = resolveUserTransactionName( props );
+    log.trace( "Configured JTATransactionFactory to use [" + userTransactionName + "] for UserTransaction JDNI namespace" );
+  }
+
+  /**
+   * Given the lot of Hibernate configuration properties, resolve appropriate
+   * reference to JNDI {@(protected)}.
+   * <p/>
+   * In general, the properties in which we are interested here all begin with
+   * <tt>hibernate.jndi</tt>. Especially important depending on your
+   * environment are {@(protected)
+   * {@(protected)}
+   *
+   * @param properties The Hibernate config properties.
+   * @return The resolved InitialContext.
+   */
+  protected final InitialContext resolveInitialContext(Properties properties) {
   try {
-      context = NamingHelper.getInitialContext(props);
+      return NamingHelper.getInitialContext( properties );
   }
-    catch (NamingException ne) {
-      log.error("Could not obtain initial context", ne);
+    catch ( NamingException ne ) {
     throw new HibernateException( "Could not obtain initial context", ne );
   }
+  }

-    utName = props.getProperty(Environment.USER_TRANSACTION);
+  /**
+   * Given the lot of Hibernate configuration properties, resolve appropriate
+   * JNDI namespace to use for {@(protected).
+   * <p/>
+   * We determine the namespace to use by<ol>
+   * <li>Any specified {@(protected)>
+   * <li>If a {@(protected)
+   * {@(protected)>
+   * <li>finally, as a last resort, we use {@(protected)>
+   * </ol>
+   *
+   * @param properties The Hibernate config properties.
+   * @return The resolved {@(protected)
+   */
+  protected final String resolveUserTransactionName(Properties properties) {
+    String utName = properties.getProperty( Environment.USER_TRANSACTION );
+    if ( utName == null ) {
+      TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
+      if ( lookup != null ) {
+        utName = lookup.getUserTransactionName();
+      }
+    }
+    return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
+  }

-    if (utName==null) {
-      TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup(props);
-      if (lookup!=null) utName = lookup.getUserTransactionName();
+  /**
+   * {@(protected)}
+   */
+  public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+      throws HibernateException {
+    UserTransaction ut = getUserTransaction();
+    return new JTATransaction( ut, jdbcContext, transactionContext );
+  }
+
+  /**
+   * Get the {@(protected).
+   *
+   * @return The appropriate {@(protected).
+   */
+  protected UserTransaction getUserTransaction() {
+    log.trace( "Attempting to locate UserTransaction via JNDI [" + getUserTransactionName() + "]" );
+
+    try {
+      UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( getUserTransactionName() );
+      if ( ut == null ) {
+        throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + getUserTransactionName() +"]" );
+      }
+
+      log.trace( "Obtained UserTransaction" );
+
+      return ut;
   }
+    catch ( NamingException ne ) {
+      throw new TransactionException( "Could not find UserTransaction in JNDI [" + getUserTransaction() + "]", ne );
+    }
+  }

-    if (utName==null) utName = DEFAULT_USER_TRANSACTION_NAME;
+  /**
+   * Getter for property 'initialContext'.
+   *
+   * @return Value for property 'initialContext'.
+   */
+  protected InitialContext getInitialContext() {
+    return initialContext;
 }

-  public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
-  throws HibernateException {
-    return new JTATransaction(context, utName, jdbcContext, transactionContext);
+  /**
+   * Getter for property 'userTransactionName'.
+   * The algorithm here is
+   *
+   * @return Value for property 'userTransactionName'.
+   */
+  protected String getUserTransactionName() {
+    return userTransactionName;
 }

+  /**
+   * {@(protected)}
+   */
 public ConnectionReleaseMode getDefaultReleaseMode() {
   return ConnectionReleaseMode.AFTER_STATEMENT;
 }

+  /**
+   * {@(protected)}
+   */
 public boolean isTransactionManagerRequired() {
   return false;
 }

+  /**
+   * {@(protected)}
+   */
 public boolean areCallbacksLocalToHibernateTransactions() {
   return false;
 }

+  /**
+   * {@(protected)}
+   */
 public boolean isTransactionInProgress(
     JDBCContext jdbcContext,
-       Context transactionContext,
-       Transaction transaction) {
+      Context transactionContext,
+      Transaction transaction) {
   try {
-        // Essentially:
+      // Essentially:
     // 1) If we have a local (Hibernate) transaction in progress
     //    and it already has the UserTransaction cached, use that
     //    UserTransaction to determine the status.
@@(protected) @@
     // 3) Finally, as the last resort, try to lookup the
     //    UserTransaction via JNDI and use that to determine the
     //    status.
-        if ( transaction != null ) {
+      if ( transaction != null ) {
       UserTransaction ut = ( ( JTATransaction ) transaction ).getUserTransaction();
-           if ( ut != null ) {
-             return JTAHelper.isInProgress( ut.getStatus() );
-           }
-        }
+        if ( ut != null ) {
+          return JTAHelper.isInProgress( ut.getStatus() );
+        }
+      }

-        if ( jdbcContext.getFactory().getTransactionManager() != null ) {
-           return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
-        }
-        else {
-           try {
-          UserTransaction ut = ( UserTransaction ) context.lookup( utName );
-           return ut != null && JTAHelper.isInProgress( ut.getStatus() );
-        }
-        catch ( NamingException ne ) {
-          throw new TransactionException( "Unable to locate UserTransaction to check status", ne );
-        }
-        }
+      if ( jdbcContext.getFactory().getTransactionManager() != null ) {
+        return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
+      }
+      else {
+        UserTransaction ut = getUserTransaction();
+        return ut != null && JTAHelper.isInProgress( ut.getStatus() );
+      }
   }
-    catch( SystemException se ) {
+    catch ( SystemException se ) {
     throw new TransactionException( "Unable to check transaction status", se );
   }
 }

_______________________________________________
hibernate-commits mailing list
hibernate-commits@(protected)
https://lists.jboss.org/mailman/listinfo/hibernate-commits
©2008 gg3721.com - Jax Systems, LLC, U.S.A.