commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ozeigerm...@apache.org
Subject cvs commit: jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory TransactionalMapWrapper.java
Date Sat, 05 Jun 2004 16:33:37 GMT
ozeigermann    2004/06/05 09:33:37

  Modified:    transaction/src/java/org/apache/commons/transaction/memory
                        TransactionalMapWrapper.java
  Log:
  - Added Javadocs
  - Removed obsolete rollbackonly flag
  - Added suspended flag
  
  Revision  Changes    Path
  1.16      +144 -27   jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java
  
  Index: TransactionalMapWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- TransactionalMapWrapper.java	5 Jun 2004 14:52:09 -0000	1.15
  +++ TransactionalMapWrapper.java	5 Jun 2004 16:33:37 -0000	1.16
  @@ -54,16 +54,19 @@
    */
   public class TransactionalMapWrapper implements Map, Status {
   
  +	/** The map wrapped. */
       protected Map wrapped;
   
  -    protected ThreadLocal activeTx = new ThreadLocal();
  -
  +	/** Factory to be used to create temporary maps for transactions. */
       protected MapFactory mapFactory;
  +	/** Factory to be used to create temporary sets for transactions. */
       protected SetFactory setFactory;
   
  +	private ThreadLocal activeTx = new ThreadLocal();
  +
       /**
        * Creates a new transactional map wrapper. Temporary maps and sets to store transactional
  -     * data will be instances of {@link HashMap} and {@link HashSet}. 
  +     * data will be instances of {@link java.util.HashMap} and {@link java.util.HashSet}.

        * 
        * @param wrapped map to be wrapped
        */
  @@ -85,6 +88,12 @@
           this.setFactory = setFactory;
       }
   
  +    /**
  +     * Checks if any write operations have been performed inside this transaction.
  +     * 
  +     * @return <code>true</code> if no write opertation has been performed
inside the current transaction,
  +     * <code>false</code> otherwise
  +     */
       public synchronized boolean isReadOnly() {
           TxContext txContext = getActiveTx();
   
  @@ -96,6 +105,16 @@
           return txContext.readOnly;
       }
   
  +    /**
  +     * Checks whether this transaction has been marked to allow a rollback as the only
  +     * valid outcome. This can be set my method {@link #markTransactionForRollback()} or
might
  +     * be set internally be any fatal error. Once a transaction is marked for rollback
there
  +     * is no way to undo this. A transaction that is marked for rollback can not be committed,
  +     * also rolled back. 
  +     * 
  +     * @return <code>true</code> if this transaction has been marked for a
roll back
  +     * @see #markTransactionForRollback()
  +     */
       public synchronized boolean isTransactionMarkedForRollback() {
           TxContext txContext = getActiveTx();
   
  @@ -104,9 +123,14 @@
                   "Active thread " + Thread.currentThread() + " not associated with a transaction!");
           }
   
  -        return txContext.rollbackOnly;
  +        return (txContext.status == Status.STATUS_MARKED_ROLLBACK);
       }
   
  +	/**
  +	 * Marks the current transaction to allow only a rollback as valid outcome. 
  +	 *
  +	 * @see #isTransactionMarkedForRollback()
  +	 */
       public synchronized void markTransactionForRollback() {
           TxContext txContext = getActiveTx();
   
  @@ -115,10 +139,24 @@
                   "Active thread " + Thread.currentThread() + " not associated with a transaction!");
           }
   
  -        txContext.rollbackOnly = true;
  -
  +		txContext.status = Status.STATUS_MARKED_ROLLBACK;
       }
   
  +	/**
  +	 * Suspends the transaction associated to the current thread. I.e. the associated between
the 
  +	 * current thread and the transaction is deleted. This is useful when you want to continue
the transaction
  +	 * in another thread later. Call {@link #resumeTransaction(TxContext)} - possibly in another
thread than the current - 
  +	 * to resume work on the transaction.  
  +	 * <br><br>
  +	 * <em>Caution:</em> When calling this method the returned identifier
  +	 * for the transaction is the only remaining reference to the transaction, so be sure
to remember it or
  +	 * the transaction will be eventually deleted (and thereby rolled back) as garbage.
  +	 * 
  +	 * @return an identifier for the suspended transaction, will be needed to later resume
the transaction by
  +	 * {@link #resumeTransaction(TxContext)} 
  +	 * 
  +	 * @see #resumeTransaction(TxContext)
  +	 */
       public synchronized TxContext suspendTransaction() {
           TxContext txContext = getActiveTx();
   
  @@ -127,10 +165,18 @@
                   "Active thread " + Thread.currentThread() + " not associated with a transaction!");
           }
   
  -        setActiveTx(null);
  +		txContext.suspended = true;
  +		setActiveTx(null);
           return txContext;
       }
   
  +	/**
  +	 * Resumes a transaction in the current thread that has previously been suspened by {@link
#suspendTransaction()}.
  +	 * 
  +	 * @param suspendedTx the identifier for the transaction to be resumed, delivered by {@link
#suspendTransaction()} 
  +	 * 
  +	 * @see #suspendTransaction()
  +	 */
       public synchronized void resumeTransaction(TxContext suspendedTx) {
           if (getActiveTx() != null) {
               throw new IllegalStateException(
  @@ -140,10 +186,20 @@
           if (suspendedTx == null) {
               throw new IllegalStateException("No transaction to resume!");
           }
  +        
  +        if (!suspendedTx.suspended) {
  +			throw new IllegalStateException("Transaction to resume needs to be suspended!");
  +        }
   
  +		suspendedTx.suspended = false;
           setActiveTx(suspendedTx);
       }
   
  +	/**
  +	 * Returns the state of the current transaction.
  +	 * 
  +	 * @return state of the current transaction as decribed in the {@link Status} interface.
  +	 */
       public synchronized int getTransactionState() {
           TxContext txContext = getActiveTx();
   
  @@ -153,6 +209,18 @@
           return txContext.status;
       }
   
  +    /**
  +     * Starts a new transaction and associates it with the current thread. All subsequent
changes in the same
  +     * thread made to the map are invisible from other threads until {@link #commitTransaction()}
is called.
  +     * Use {@link #rollbackTransaction()} to discard your changes. After calling either
method there will be
  +     * no transaction associated to the current thread any longer. 
  + 	 * <br><br>
  +     * <em>Caution:</em> Be careful to finally call one of those methods,
  +     * as otherwise the transaction will lurk around for ever.
  +     *
  +     * @see #commitTransaction()
  +     * @see #rollbackTransaction()
  +     */
       public synchronized void startTransaction() {
           if (getActiveTx() != null) {
               throw new IllegalStateException(
  @@ -161,6 +229,13 @@
           setActiveTx(new TxContext());
       }
   
  +    /**
  +     * Discards all changes made in the current transaction and deletes the association
between the current thread
  +     * and the transaction.
  +     * 
  +     * @see #startTransaction()
  +     * @see #commitTransaction()
  +     */
       public synchronized void rollbackTransaction() {
           TxContext txContext = getActiveTx();
   
  @@ -174,6 +249,13 @@
           setActiveTx(null);
       }
   
  +    /**
  +     * Commits all changes made in the current transaction and deletes the association
between the current thread
  +     * and the transaction.
  +     *  
  +     * @see #startTransaction()
  +     * @see #rollbackTransaction()
  +     */
       public synchronized void commitTransaction() {
           TxContext txContext = getActiveTx();
   
  @@ -182,7 +264,7 @@
                   "Active thread " + Thread.currentThread() + " not associated with a transaction!");
           }
   
  -        if (txContext.rollbackOnly) {
  +        if (txContext.status == Status.STATUS_MARKED_ROLLBACK) {
               throw new IllegalStateException("Active thread " + Thread.currentThread() +
" is marked for rollback!");
           }
   
  @@ -195,6 +277,9 @@
       // Map methods
       // 
   
  +	/**
  +	 * @see Map#clear() 
  +	 */
       public synchronized void clear() {
           TxContext txContext = getActiveTx();
           if (txContext != null) {
  @@ -204,6 +289,9 @@
           }
       }
   
  +    /**
  +     * @see Map#size() 
  +     */
       public synchronized int size() {
           TxContext txContext = getActiveTx();
           if (txContext != null) {
  @@ -213,6 +301,9 @@
           }
       }
   
  +    /**
  +     * @see Map#isEmpty() 
  +     */
       public synchronized boolean isEmpty() {
           TxContext txContext = getActiveTx();
           if (txContext == null) {
  @@ -222,10 +313,16 @@
           }
       }
   
  +    /**
  +     * @see Map#containsKey(java.lang.Object) 
  +     */
       public synchronized boolean containsKey(Object key) {
           return (get(key) != null);
       }
   
  +    /**
  +     * @see Map#containsValue(java.lang.Object) 
  +     */
       public synchronized boolean containsValue(Object value) {
           TxContext txContext = getActiveTx();
   
  @@ -236,6 +333,9 @@
           }
       }
   
  +    /**
  +     * @see Map#values() 
  +     */
       public synchronized Collection values() {
   
           TxContext txContext = getActiveTx();
  @@ -254,6 +354,9 @@
           }
       }
   
  +    /**
  +     * @see Map#putAll(java.util.Map) 
  +     */
       public synchronized void putAll(Map map) {
           TxContext txContext = getActiveTx();
   
  @@ -267,6 +370,9 @@
           }
       }
   
  +    /**
  +     * @see Map#entrySet() 
  +     */
       public synchronized Set entrySet() {
           TxContext txContext = getActiveTx();
           if (txContext == null) {
  @@ -283,6 +389,9 @@
           }
       }
   
  +    /**
  +     * @see Map#keySet() 
  +     */
       public synchronized Set keySet() {
           TxContext txContext = getActiveTx();
   
  @@ -293,6 +402,9 @@
           }
       }
   
  +    /**
  +     * @see Map#get(java.lang.Object) 
  +     */
       public synchronized Object get(Object key) {
           TxContext txContext = getActiveTx();
   
  @@ -303,6 +415,9 @@
           }
       }
   
  +    /**
  +     * @see Map#remove(java.lang.Object) 
  +     */
       public synchronized Object remove(Object key) {
           TxContext txContext = getActiveTx();
   
  @@ -315,6 +430,9 @@
           }
       }
   
  +    /**
  +     * @see Map#put(java.lang.Object, java.lang.Object)
  +     */
       public synchronized Object put(Object key, Object value) {
           TxContext txContext = getActiveTx();
   
  @@ -387,26 +505,25 @@
           protected Set deletes;
           protected Map changes;
           protected Map adds;
  -        protected boolean rollbackOnly;
           protected int status;
           protected boolean cleared;
           protected boolean readOnly;
  +        protected boolean suspended = false;
   
           protected TxContext() {
               deletes = setFactory.createSet();
               changes = mapFactory.createMap();
               adds = mapFactory.createMap();
  -            rollbackOnly = false;
               status = Status.STATUS_ACTIVE;
               cleared = false;
               readOnly = true;
           }
   
           protected Set keys() {
  -			Set keySet = new HashSet();
  -			if (!cleared) {
  -				keySet.addAll(wrapped.keySet());
  -			}
  +            Set keySet = new HashSet();
  +            if (!cleared) {
  +                keySet.addAll(wrapped.keySet());
  +            }
               keySet.addAll(adds.keySet());
               return keySet;
           }
  @@ -446,10 +563,10 @@
                       adds.put(key, value);
                   }
               } catch (RuntimeException e) {
  -                rollbackOnly = true;
  +                status = Status.STATUS_MARKED_ROLLBACK;
                   throw e;
               } catch (Error e) {
  -                rollbackOnly = true;
  +                status = Status.STATUS_MARKED_ROLLBACK;
                   throw e;
               }
           }
  @@ -458,16 +575,16 @@
   
               try {
                   readOnly = false;
  -				changes.remove(key);
  +                changes.remove(key);
                   adds.remove(key);
                   if (wrapped.containsKey(key) && !cleared) {
  -					deletes.add(key);
  +                    deletes.add(key);
                   }
               } catch (RuntimeException e) {
  -                rollbackOnly = true;
  +                status = Status.STATUS_MARKED_ROLLBACK;
                   throw e;
               } catch (Error e) {
  -                rollbackOnly = true;
  +                status = Status.STATUS_MARKED_ROLLBACK;
                   throw e;
               }
           }
  @@ -496,8 +613,8 @@
                       wrapped.clear();
                   }
   
  -				wrapped.putAll(changes);
  -				wrapped.putAll(adds);
  +                wrapped.putAll(changes);
  +                wrapped.putAll(adds);
   
                   for (Iterator it = deletes.iterator(); it.hasNext();) {
                       Object key = it.next();
  @@ -513,7 +630,7 @@
               changes = null;
               mapFactory.disposeMap(adds);
               adds = null;
  +            status = Status.STATUS_NO_TRANSACTION;
           }
       }
  -
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message