Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 
 
 package org.apache.geronimo.transaction.manager;
 
 import java.util.List;
 import java.util.Map;
 
 
Simple implementation of a transaction manager.

Version:
$Rev: 1026099 $ $Date: 2010-10-21 20:42:58 +0200 (Thu, 21 Oct 2010) $
 
     private static final Logger log = LoggerFactory.getLogger(TransactionManagerImpl.class);
     private static final Logger recoveryLog = LoggerFactory.getLogger("RecoveryController");
 
     protected static final int DEFAULT_TIMEOUT = 600;
     protected static final byte[] DEFAULT_TM_ID = new byte[] {71,84,77,73,68};
 
     private final TransactionLog transactionLog;
     private final XidFactory xidFactory;
     private final int defaultTransactionTimeoutMilliseconds;
     private final ThreadLocal<LongtransactionTimeoutMilliseconds = new ThreadLocal<Long>();
     private final ThreadLocal<TransactionthreadTx = new ThreadLocal<Transaction>();
     final Recovery recovery;
     private final List<ExceptionrecoveryErrors = new ArrayList<Exception>();
     // statistics
     private AtomicLong totalCommits = new AtomicLong(0);
     private AtomicLong totalRollBacks = new AtomicLong(0);
     private AtomicLong activeCount = new AtomicLong(0);
 
     public TransactionManagerImpl() throws XAException {
         this(,
                 null,
                 null
         );
     }
 
     public TransactionManagerImpl(int defaultTransactionTimeoutSecondsthrows XAException {
         this(defaultTransactionTimeoutSeconds,
                 null,
                 null
         );
     }
 
     public TransactionManagerImpl(int defaultTransactionTimeoutSecondsTransactionLog transactionLogthrows XAException {
         this(defaultTransactionTimeoutSeconds,
                 null,
                 transactionLog
         );
     }
 
     public TransactionManagerImpl(int defaultTransactionTimeoutSecondsXidFactory xidFactoryTransactionLog transactionLogthrows XAException {
         if (defaultTransactionTimeoutSeconds <= 0) {
             throw new IllegalArgumentException("defaultTransactionTimeoutSeconds must be positive: attempted value: " + defaultTransactionTimeoutSeconds);
         }
         this. = defaultTransactionTimeoutSeconds * 1000;
 
         if (transactionLog == null) {
             this. = new UnrecoverableLog();
         } else {
             this. = transactionLog;
         }
 
         if (xidFactory != null) {
             this. = xidFactory;
         } else {
            this. = new XidFactoryImpl();
        }
         = new RecoveryImpl(this);
        .recoverLog();
    }
    public Transaction getTransaction() {
        return .get();
    }
    private void associate(TransactionImpl txthrows InvalidTransactionException {
        if (tx.getStatus() == .) {
            throw new InvalidTransactionException("Cannot resume invalid transaction: " + tx);
        } else {
            Object existingAssociation = .putIfAbsent(tx, Thread.currentThread());
            if (existingAssociation != null) {
                throw new InvalidTransactionException("Specified transaction is already associated with another thread");
            }
            .set(tx);
            fireThreadAssociated(tx);
            .getAndIncrement();
        }
    } 
    private void unassociate() {
        Transaction tx = getTransaction();
        if (tx != null) {
            .remove(tx);
            .set(null);
            fireThreadUnassociated(tx);
            .getAndDecrement();
        }
    }
    public void setTransactionTimeout(int secondsthrows SystemException {
        if (seconds < 0) {
            throw new SystemException("transaction timeout must be positive or 0 to reset to default");
        }
        if (seconds == 0) {
            .set(null);
        } else {
            .set((longseconds * 1000);
        }
    }
    public int getStatus() throws SystemException {
        Transaction tx = getTransaction();
        return (tx != null) ? tx.getStatus() : .;
    }
    public void begin() throws NotSupportedExceptionSystemException {
    }
    public Transaction begin(long transactionTimeoutMillisecondsthrows NotSupportedExceptionSystemException {
        if (getStatus() != .) {
            throw new NotSupportedException("Nested Transactions are not supported");
        }
        TransactionImpl tx = new TransactionImpl(thisgetTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
//        timeoutTimer.schedule(tx, getTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
        try {
            associate(tx);
        } catch (InvalidTransactionException e) {
            // should not be possible since we just created that transaction and no one has a reference yet
            throw (SystemException)new SystemException("Internal error: associate threw an InvalidTransactionException for a newly created transaction").initCause(e);
        }
        // Todo: Verify if this is correct thing to do. Use default timeout for next transaction.
        this..set(null);
        return tx;
    }
    public Transaction suspend() throws SystemException {
        Transaction tx = getTransaction();
        if (tx != null) {
            unassociate();
        }
        return tx;
    }
        if (getTransaction() != null && tx != getTransaction()) {
            throw new IllegalStateException("Thread already associated with another transaction");
        }
        if (tx != null && tx != getTransaction()) {
            if (!(tx instanceof TransactionImpl)) {
                throw new InvalidTransactionException("Cannot resume foreign transaction: " + tx);
            }
            
            associate((TransactionImpltx);
        }
    }
    public Object getResource(Object key) {
        TransactionImpl tx = getActiveTransactionImpl();
        return tx.getResource(key);
    }
        TransactionImpl tx = (TransactionImpl).get();
        if (tx == null) {
            throw new IllegalStateException("No tx on thread");
        }
        if (tx.getStatus() != . && tx.getStatus() != .) {
            throw new IllegalStateException("Transaction " + tx + " is not active");
        }
        return tx;
    }
    public boolean getRollbackOnly() {
        TransactionImpl tx = getActiveTransactionImpl();
        return tx.getRollbackOnly();
    }
    public Object getTransactionKey() {
        return tx == null ? nulltx.getTransactionKey();
    }
    public int getTransactionStatus() {
        TransactionImpl tx = (TransactionImplgetTransaction();
        return tx == null.tx.getTransactionStatus();
    }
    public void putResource(Object keyObject value) {
        TransactionImpl tx = getActiveTransactionImpl();
        tx.putResource(keyvalue);
    }

    
jta 1.1 method so the jpa implementations can be told to flush their caches.

Parameters:
synchronization interposed synchronization
    public void registerInterposedSynchronization(Synchronization synchronization) {
        TransactionImpl tx = getActiveTransactionImpl();
        tx.registerInterposedSynchronization(synchronization);
    }
    public void setRollbackOnly() throws IllegalStateException {
        TransactionImpl tx = (TransactionImpl.get();
        if (tx == null) {
            throw new IllegalStateException("No transaction associated with current thread");
        }
        tx.setRollbackOnly();
    }
        Transaction tx = getTransaction();
        if (tx == null) {
            throw new IllegalStateException("No transaction associated with current thread");
        }
        try {
            tx.commit();
        } finally {
            unassociate();
        }
        .getAndIncrement();
    }
    public void rollback() throws IllegalStateExceptionSecurityExceptionSystemException {
        Transaction tx = getTransaction();
        if (tx == null) {
            throw new IllegalStateException("No transaction associated with current thread");
        }
        try {
            tx.rollback();
        } finally {
            unassociate();
        }
    }
    //XidImporter implementation
    public Transaction importXid(Xid xidlong transactionTimeoutMillisecondsthrows XAExceptionSystemException {
        if (transactionTimeoutMilliseconds < 0) {
            throw new SystemException("transaction timeout must be positive or 0 to reset to default");
        }
        return new TransactionImpl(xidthisgetTransactionTimeoutMilliseconds(transactionTimeoutMilliseconds));
    }
    public void commit(Transaction txboolean onePhasethrows XAException {
        if (onePhase) {
            try {
                tx.commit();
            } catch (HeuristicMixedException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (HeuristicRollbackException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (RollbackException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (SecurityException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (SystemException e) {
                throw (XAExceptionnew XAException().initCause(e);
            }
        } else {
            try {
                ((TransactionImpltx).preparedCommit();
            } catch (HeuristicMixedException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (HeuristicRollbackException e) {
                throw (XAExceptionnew XAException().initCause(e);
            } catch (SystemException e) {
                throw (XAExceptionnew XAException().initCause(e);
            }
        }
        .getAndIncrement();
    }
    public void forget(Transaction txthrows XAException {
        //TODO implement this!
    }
    public int prepare(Transaction txthrows XAException {
        try {
            return ((TransactionImpltx).prepare();
        } catch (SystemException e) {
            throw (XAExceptionnew XAException().initCause(e);
        } catch (RollbackException e) {
            throw (XAExceptionnew XAException().initCause(e);
        }
    }
    public void rollback(Transaction txthrows XAException {
        try {
            tx.rollback();
        } catch (IllegalStateException e) {
            throw (XAExceptionnew XAException().initCause(e);
        } catch (SystemException e) {
            throw (XAExceptionnew XAException().initCause(e);
        }
    }
    long getTransactionTimeoutMilliseconds(long transactionTimeoutMilliseconds) {
        if (transactionTimeoutMilliseconds != 0) {
            return transactionTimeoutMilliseconds;
        }
        Long timeout = this..get();
        if (timeout != null) {
            return timeout;
        }
    }
    //Recovery
    public void recoveryError(Exception e) {
        .error("Recovery error: {}"e.getMessage());
        .add(e);
    }
    public void registerNamedXAResourceFactory(NamedXAResourceFactory namedXAResourceFactory) {
        .put(namedXAResourceFactory.getName(), namedXAResourceFactory);
        new RecoverTask(namedXAResourceFactorythis).run();
    }
    public void unregisterNamedXAResourceFactory(String namedXAResourceFactoryName) {
        .remove(namedXAResourceFactoryName);
    }
        return .get(xaResourceName);
    }
        return ;
    }
        return ;
    }
        return ;
    }
    public Map<XidTransactionImplgetExternalXids() {
        return new HashMap<XidTransactionImpl>(.getExternalXids());
    }
    }
        .remove(listener);
    }
    protected void fireThreadAssociated(Transaction tx) {
        for (TransactionManagerMonitor listener : ) {
            try {
                listener.threadAssociated(tx);
            } catch (Exception e) {
                .warn("Error calling transaction association listener"e);
            }
        }
    }
    protected void fireThreadUnassociated(Transaction tx) {
        for (TransactionManagerMonitor listener : ) {
            try {
                listener.threadUnassociated(tx);
            } catch (Exception e) {
                .warn("Error calling transaction association listener"e);
            }
        }
    }

    
Returns the number of active transactions.

Returns:
the count of active transactions
    public long getActiveCount() {
        return .longValue();
    }

    
Return the number of total commits

Returns:
the number of commits since statistics were reset
    public long getTotalCommits() {
        return .longValue();
    }

    
Returns the number of total rollbacks

Returns:
the number of rollbacks since statistics were reset
    public long getTotalRollbacks() {
        return .longValue();
    }

    
Reset statistics
    public void resetStatistics() {
        .getAndSet(0);
        .getAndSet(0);
    }
New to GrepCode? Check out our FAQ X