Home » apache-openjpa-1.1.0-source » org.apache.openjpa » kernel » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.    
   18    */
   19   package org.apache.openjpa.kernel;
   20   
   21   import javax.transaction.NotSupportedException;
   22   import javax.transaction.Status;
   23   import javax.transaction.Synchronization;
   24   import javax.transaction.SystemException;
   25   import javax.transaction.Transaction;
   26   import javax.transaction.TransactionManager;
   27   import javax.transaction.xa.XAResource;
   28   
   29   import org.apache.openjpa.ee.AbstractManagedRuntime;
   30   import org.apache.openjpa.ee.ManagedRuntime;
   31   import org.apache.openjpa.lib.util.Localizer;
   32   import org.apache.openjpa.util.InternalException;
   33   import org.apache.openjpa.util.InvalidStateException;
   34   import org.apache.openjpa.util.StoreException;
   35   import org.apache.openjpa.util.UserException;
   36   
   37   /**
   38    * Uses a local implementation of the {@link TransactionManager} interface.
   39    * This manager is valid only for a single {@link Broker}.
   40    * It duplicates non-managed transaction control.
   41    *
   42    * @author Abe White
   43    */
   44   class LocalManagedRuntime extends AbstractManagedRuntime
   45       implements ManagedRuntime, TransactionManager, Transaction {
   46   
   47       private static final Localizer _loc = Localizer.forPackage
   48           (LocalManagedRuntime.class);
   49   
   50       private Synchronization _broker = null;
   51       private Synchronization _factorySync = null;
   52       private boolean _active = false;
   53       private Throwable _rollbackOnly = null;
   54   
   55       /**
   56        * Constructor. Provide broker that will be requesting managed
   57        * transaction info.
   58        */
   59       public LocalManagedRuntime(Broker broker) {
   60           _broker = broker;
   61       }
   62   
   63       public TransactionManager getTransactionManager() {
   64           return this;
   65       }
   66   
   67       public synchronized void begin() {
   68           if (_active)
   69               throw new InvalidStateException(_loc.get("active"));
   70           _active = true;
   71       }
   72   
   73       public synchronized void commit() {
   74           if (!_active)
   75               throw new InvalidStateException(_loc.get("not-active"));
   76   
   77           // try to invoke before completion in preparation for commit
   78           RuntimeException err = null;
   79           if (_rollbackOnly == null) {
   80               try {
   81                   _broker.beforeCompletion();
   82                   if (_factorySync != null)
   83                       _factorySync.beforeCompletion();
   84               } catch (RuntimeException re) {
   85                   _rollbackOnly = re;
   86                   err = re;
   87               }
   88           } else // previously marked rollback only
   89               err = new StoreException(_loc.get("marked-rollback")).
   90                   setCause(_rollbackOnly).setFatal(true);
   91   
   92           if (_rollbackOnly == null) {
   93               try {
   94                   _broker.afterCompletion(Status.STATUS_COMMITTED);
   95                   notifyAfterCompletion(Status.STATUS_COMMITTED);
   96               } catch (RuntimeException re) {
   97                   if (err == null)
   98                       err = re;
   99               }
  100           }
  101   
  102           // if we haven't managed to commit, rollback
  103           if (_active) {
  104               try {
  105                   rollback();
  106               } catch (RuntimeException re) {
  107                   if (err == null)
  108                       err = re;
  109               }
  110           }
  111   
  112           // throw the first exception we encountered, if any
  113           if (err != null)
  114               throw err;
  115       }
  116   
  117       public synchronized void rollback() {
  118           if (!_active)
  119               throw new InvalidStateException(_loc.get("not-active"));
  120   
  121           // rollback broker
  122           RuntimeException err = null;
  123           try {
  124               _broker.afterCompletion(Status.STATUS_ROLLEDBACK);
  125           } catch (RuntimeException re) {
  126               err = re;
  127           }
  128   
  129           // rollback synch, even if broker throws exception
  130           try {
  131               notifyAfterCompletion(Status.STATUS_ROLLEDBACK);
  132           } catch (RuntimeException re) {
  133               if (err == null)
  134                   err = re;
  135           }
  136   
  137           if (err != null)
  138               throw err;
  139       }
  140   
  141       /**
  142        * Notifies the factory sync that the transaction has ended with
  143        * the given status. Clears all transaction state regardless
  144        * of any exceptions during the callback.
  145        */
  146       private void notifyAfterCompletion(int status) {
  147           _active = false;
  148   
  149           try {
  150               if (_factorySync != null)
  151                   _factorySync.afterCompletion(status);
  152           } finally {
  153               _rollbackOnly = null;
  154               _factorySync = null;
  155           }
  156       }
  157   
  158       public synchronized void setRollbackOnly() {
  159           setRollbackOnly(new UserException());
  160       }
  161   
  162       public void setRollbackOnly(Throwable cause) {
  163           _rollbackOnly = cause;
  164       }
  165   
  166       public Throwable getRollbackCause() {
  167           return _rollbackOnly;
  168       }
  169   
  170       public synchronized int getStatus() {
  171           if (_rollbackOnly != null)
  172               return Status.STATUS_MARKED_ROLLBACK;
  173           if (_active)
  174               return Status.STATUS_ACTIVE;
  175           return Status.STATUS_NO_TRANSACTION;
  176       }
  177   
  178       public Transaction getTransaction() {
  179           return this;
  180       }
  181   
  182       public void resume(Transaction tobj)
  183           throws SystemException {
  184           throw new SystemException(NotSupportedException.class.getName());
  185       }
  186   
  187       public void setTransactionTimeout(int sec)
  188           throws SystemException {
  189           throw new SystemException(NotSupportedException.class.getName());
  190       }
  191   
  192       public Transaction suspend()
  193           throws SystemException {
  194           throw new SystemException(NotSupportedException.class.getName());
  195       }
  196   
  197       public boolean delistResource(XAResource xaRes, int flag)
  198           throws SystemException {
  199           throw new SystemException(NotSupportedException.class.getName());
  200       }
  201   
  202       public boolean enlistResource(XAResource xaRes)
  203           throws SystemException {
  204           throw new SystemException(NotSupportedException.class.getName());
  205       }
  206   
  207       public synchronized void registerSynchronization(Synchronization sync) {
  208           if (sync == _broker)
  209               return;
  210           if (_factorySync != null)
  211               throw new InternalException();
  212           _factorySync = sync;
  213       }
  214   }
  215   

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa » kernel » [javadoc | source]