Search in sources :

Example 1 with NucleusTransactionException

use of org.datanucleus.transaction.NucleusTransactionException in project datanucleus-core by datanucleus.

the class TransactionImpl method commit.

/**
 * Method to commit the transaction.
 */
public void commit() {
    if (!isActive()) {
        throw new TransactionNotActiveException();
    }
    // the exception and call rollback themselves. i.e we don't need to close the DB connection or set "active" to false.
    if (rollbackOnly) {
        // Throw an exception since can only exit via rollback
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(Localiser.msg("015020"));
        }
        throw new NucleusDataStoreException(Localiser.msg("015020")).setFatal();
    }
    long startTime = System.currentTimeMillis();
    boolean success = false;
    // whether the transaction can be completed
    boolean canComplete = true;
    List<Throwable> errors = new ArrayList();
    try {
        // TODO Is this needed? om.preCommit will handle flush calls
        flush();
        internalPreCommit();
        internalCommit();
        success = true;
    } catch (RollbackException e) {
        // in Transaction.Synchronization and they should cascade up to user code
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(StringUtils.getStringFromStackTrace(e));
        }
        errors.add(e);
    } catch (HeuristicRollbackException e) {
        // in Transaction.Synchronization and they should cascade up to user code
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(StringUtils.getStringFromStackTrace(e));
        }
        errors.add(e);
    } catch (HeuristicMixedException e) {
        // in Transaction.Synchronization and they should cascade up to user code
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(StringUtils.getStringFromStackTrace(e));
        }
        errors.add(e);
    } catch (NucleusUserException e) {
        // they must be cascade up to user code and transaction is still alive
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(StringUtils.getStringFromStackTrace(e));
        }
        canComplete = false;
        throw e;
    } catch (NucleusException e) {
        // in Transaction.Synchronization and they should cascade up to user code
        if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
            NucleusLogger.TRANSACTION.debug(StringUtils.getStringFromStackTrace(e));
        }
        errors.add(e);
    } finally {
        if (canComplete) {
            try {
                if (!success) {
                    rollback();
                } else {
                    internalPostCommit();
                }
            } catch (Throwable e) {
                errors.add(e);
            }
        }
    }
    if (!errors.isEmpty()) {
        throw new NucleusTransactionException(Localiser.msg("015007"), errors.toArray(new Throwable[errors.size()]));
    }
    if (NucleusLogger.TRANSACTION.isDebugEnabled()) {
        NucleusLogger.TRANSACTION.debug(Localiser.msg("015022", System.currentTimeMillis() - startTime));
    }
}
Also used : NucleusTransactionException(org.datanucleus.transaction.NucleusTransactionException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ArrayList(java.util.ArrayList) HeuristicRollbackException(org.datanucleus.transaction.HeuristicRollbackException) RollbackException(org.datanucleus.transaction.RollbackException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) HeuristicRollbackException(org.datanucleus.transaction.HeuristicRollbackException) TransactionNotActiveException(org.datanucleus.exceptions.TransactionNotActiveException) HeuristicMixedException(org.datanucleus.transaction.HeuristicMixedException) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 2 with NucleusTransactionException

use of org.datanucleus.transaction.NucleusTransactionException in project datanucleus-core by datanucleus.

the class JTAJCATransactionImpl method joinTransaction.

// ------------------- Methods to get the JTA transaction for synchronising --------------------------
/**
 * Synchronise our active state with that of the JTA transaction, if it exists.
 * Look for an active JTA transaction. if there is one, begin() ourselves
 * and register synchronisation. We must poll because there is no
 * way of getting notified of a newly begun transaction.<p>
 */
private synchronized void joinTransaction() {
    if (active) {
        return;
    }
    // try to registerSynchronization()
    try {
        if (jtaTM == null) {
            // Retrieve the JTA TransactionManager. Unfortunately, before JavaEE 5 there is no specified way to do it,
            // only app-server-specific ways. In JavaEE 5, we can use TransactionSynchronizationRegistry
            jtaTM = ec.getNucleusContext().getJtaTransactionManager();
            if (jtaTM == null) {
                throw new NucleusTransactionException(Localiser.msg("015030"));
            }
        }
        jtaTx = jtaTM.getTransaction();
        if (jtaTx != null && jtaTx.getStatus() == Status.STATUS_ACTIVE) {
            if (// TODO Aren't we always in JCA mode with this class?
            !ec.getNucleusContext().isJcaMode()) {
                // in JCA mode, we do not register Synchronization TODO Use JtaSyncRegistry if available?
                jtaTx.registerSynchronization(this);
            }
            // the transaction is active here
            begin();
        } else {
            // If a transaction was marked for rollback before we could register synchronisation, we won't be called back when it is rolled back
            if (markedForRollback) {
                // as jtaTx is null there is no active transaction, meaning that the jtaTx was actually rolled back after it had been marked for rollback: catch up
                rollback();
                markedForRollback = false;
            }
        }
    } catch (SystemException se) {
        throw new NucleusTransactionException(Localiser.msg("015026"), se);
    } catch (RollbackException e) {
        NucleusLogger.TRANSACTION.error("Exception while joining transaction: " + StringUtils.getStringFromStackTrace(e));
    // tx is marked for rollback: leave registeredSynchronizationOnJtaTx==false so that we try to register again next time we're called
    }
}
Also used : NucleusTransactionException(org.datanucleus.transaction.NucleusTransactionException) SystemException(javax.transaction.SystemException) RollbackException(javax.transaction.RollbackException)

Example 3 with NucleusTransactionException

use of org.datanucleus.transaction.NucleusTransactionException in project datanucleus-core by datanucleus.

the class JTATransactionImpl method joinTransaction.

/**
 * Method to call if you want to join to the underlying UserTransaction.
 * Will be called by isActive() and constructor if "autoJoin" is set, otherwise has to be called by user code.
 */
public void joinTransaction() {
    if (joinStatus != JoinStatus.JOINED) {
        try {
            javax.transaction.Transaction txn = jtaTM.getTransaction();
            if (jtaTx != null && !jtaTx.equals(txn)) {
                // it should happen only if joinStatus == JOIN_STATUS_IMPOSSIBLE
                if (!(joinStatus == JoinStatus.IMPOSSIBLE)) {
                    throw new InternalError("JTA Transaction changed without being notified");
                }
                jtaTx = null;
                joinStatus = JoinStatus.NO_TXN;
                joinTransaction();
            } else {
                if (jtaTx == null) {
                    jtaTx = txn;
                    boolean allow_join = (jtaTM.getStatus() == Status.STATUS_ACTIVE);
                    if (allow_join) {
                        joinStatus = JoinStatus.IMPOSSIBLE;
                        try {
                            if (jtaSyncRegistry != null) {
                                // Register via TransactionSynchronizationRegistry
                                jtaSyncRegistry.register(this);
                            } else {
                                // Register via Transaction
                                if (jtaTx != null) {
                                    jtaTx.registerSynchronization(this);
                                }
                            }
                            if (!super.isActive()) {
                                // the transaction is active here
                                internalBegin();
                            }
                        } catch (Exception e) {
                            throw new NucleusTransactionException("Cannot register Synchronization to a valid JTA Transaction", e);
                        }
                        NucleusLogger.TRANSACTION.debug("JTA transaction for ExecutionContext=" + ec + " has JOINED to its UserTransaction");
                        joinStatus = JoinStatus.JOINED;
                    } else {
                        if (jtaTx != null) {
                            joinStatus = JoinStatus.IMPOSSIBLE;
                        }
                    }
                }
            }
        } catch (SystemException e) {
            throw new NucleusTransactionException(Localiser.msg("015026"), e);
        }
    }
}
Also used : NucleusTransactionException(org.datanucleus.transaction.NucleusTransactionException) SystemException(javax.transaction.SystemException) NucleusException(org.datanucleus.exceptions.NucleusException) NamingException(javax.naming.NamingException) NotSupportedException(javax.transaction.NotSupportedException) NucleusTransactionException(org.datanucleus.transaction.NucleusTransactionException) SystemException(javax.transaction.SystemException)

Example 4 with NucleusTransactionException

use of org.datanucleus.transaction.NucleusTransactionException in project datanucleus-core by datanucleus.

the class JTATransactionImpl method begin.

/**
 * JDO spec "16.1.3 Stateless Session Bean with Bean Managed Transactions": "acquiring a PM without beginning a UserTransaction results
 * in the PM being able to manage transaction boundaries via begin, commit, and rollback methods on JDO Transaction.
 * The PM will automatically begin the User-Transaction during Transaction.begin and automatically commit the UserTransaction during Transaction.commit"
 */
public void begin() {
    joinTransaction();
    if (joinStatus != JoinStatus.NO_TXN) {
        throw new NucleusTransactionException("JTA Transaction is already active");
    }
    UserTransaction utx;
    try {
        Context ctx = new InitialContext();
        if (// TODO If JBoss starts using the JavaEE standard location, we need to remove this alternative location
        JBOSS_SERVER) {
            // JBoss unfortunately doesn't always provide UserTransaction at the JavaEE standard location, see e.g. http://docs.jboss.org/admin-devel/Chap4.html
            try {
                utx = (UserTransaction) ctx.lookup("UserTransaction");
            } catch (NamingException e) {
                // Fallback to standard location
                utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
            }
        } else {
            utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
        }
    } catch (NamingException e) {
        throw ec.getApiAdapter().getUserExceptionForException("Failed to obtain JTA UserTransaction", e);
    }
    try {
        utx.begin();
    } catch (NotSupportedException | SystemException e) {
        throw ec.getApiAdapter().getUserExceptionForException("Failed to begin JTA UserTransaction", e);
    }
    joinTransaction();
    if (joinStatus != JoinStatus.JOINED) {
        throw new NucleusTransactionException("Cannot join an auto started JTA UserTransaction");
    }
    userTransaction = utx;
}
Also used : NucleusTransactionException(org.datanucleus.transaction.NucleusTransactionException) UserTransaction(javax.transaction.UserTransaction) InitialContext(javax.naming.InitialContext) Context(javax.naming.Context) SystemException(javax.transaction.SystemException) NamingException(javax.naming.NamingException) NotSupportedException(javax.transaction.NotSupportedException) InitialContext(javax.naming.InitialContext)

Aggregations

NucleusTransactionException (org.datanucleus.transaction.NucleusTransactionException)4 SystemException (javax.transaction.SystemException)3 NamingException (javax.naming.NamingException)2 NotSupportedException (javax.transaction.NotSupportedException)2 NucleusException (org.datanucleus.exceptions.NucleusException)2 ArrayList (java.util.ArrayList)1 Context (javax.naming.Context)1 InitialContext (javax.naming.InitialContext)1 RollbackException (javax.transaction.RollbackException)1 UserTransaction (javax.transaction.UserTransaction)1 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)1 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 TransactionNotActiveException (org.datanucleus.exceptions.TransactionNotActiveException)1 HeuristicMixedException (org.datanucleus.transaction.HeuristicMixedException)1 HeuristicRollbackException (org.datanucleus.transaction.HeuristicRollbackException)1 RollbackException (org.datanucleus.transaction.RollbackException)1