public void beforeCompletion()
    {
        // avoid redundant calls
        if(beforeCompletionCall) return;

        log.info("Method beforeCompletion was called");
        int status = Status.STATUS_UNKNOWN;
        try
        {
            JTATxManager mgr = (JTATxManager) getImplementation().getTxManager();
            status = mgr.getJTATransaction().getStatus();
            // ensure proper work, check all possible status
            // normally only check for 'STATUS_MARKED_ROLLBACK' is necessary
            if(status == Status.STATUS_MARKED_ROLLBACK
                    || status == Status.STATUS_ROLLEDBACK
                    || status == Status.STATUS_ROLLING_BACK
                    || status == Status.STATUS_UNKNOWN
                    || status == Status.STATUS_NO_TRANSACTION)
            {
                log.error("Synchronization#beforeCompletion: Can't prepare for commit, because tx status was "
                        + TxUtil.getStatusString(status) + ". Do internal cleanup only.");
            }
            else
            {
                if(log.isDebugEnabled())
                {
                    log.debug("Synchronization#beforeCompletion: Prepare for commit");
                }
                // write objects to database
                prepareCommit();
            }
        }
        catch(Exception e)
        {
            log.error("Synchronization#beforeCompletion: Error while prepare for commit", e);
            if(e instanceof LockNotGrantedException)
            {
                throw (LockNotGrantedException) e;
            }
            else if(e instanceof TransactionAbortedException)
            {
                throw (TransactionAbortedException) e;
            }
            else if(e instanceof ODMGRuntimeException)
            {
                throw (ODMGRuntimeException) e;
            }
            else
            { 
                throw new ODMGRuntimeException("Method beforeCompletion() fails, status of JTA-tx was "
                        + TxUtil.getStatusString(status) + ", message: " + e.getMessage());
            }

        }
        finally
        {
            beforeCompletionCall = true;
            setInExternTransaction(false);
            internalCleanup();
        }
    }
public void beforeCompletion ( ) { if ( beforeCompletionCall ) return ; log . info ( "Method beforeCompletion was called" ) ; int status = Status . STATUS_UNKNOWN ; try { JTATxManager mgr = ( JTATxManager ) getImplementation ( ) . getTxManager ( ) ; status = mgr . getJTATransaction ( ) . getStatus ( ) ; if ( status == Status . STATUS_MARKED_ROLLBACK || status == Status . STATUS_ROLLEDBACK || status == Status . STATUS_ROLLING_BACK || status == Status . STATUS_UNKNOWN || status == Status . STATUS_NO_TRANSACTION ) { log . error ( "Synchronization#beforeCompletion: Can't prepare for commit, because tx status was " + TxUtil . getStatusString ( status ) + ". Do internal cleanup only." ) ; } else { if ( log . isDebugEnabled ( ) ) { log . debug ( "Synchronization#beforeCompletion: Prepare for commit" ) ; } prepareCommit ( ) ; } } catch ( Exception e ) { log . error ( "Synchronization#beforeCompletion: Error while prepare for commit" , e ) ; if ( e instanceof LockNotGrantedException ) { throw ( LockNotGrantedException ) e ; } else if ( e instanceof TransactionAbortedException ) { throw ( TransactionAbortedException ) e ; } else if ( e instanceof ODMGRuntimeException ) { throw ( ODMGRuntimeException ) e ; } else { throw new ODMGRuntimeException ( "Method beforeCompletion() fails, status of JTA-tx was " + TxUtil . getStatusString ( status ) + ", message: " + e . getMessage ( ) ) ; } } finally { beforeCompletionCall = true ; setInExternTransaction ( false ) ; internalCleanup ( ) ; } }
FOR internal use. This method was called before the external transaction was completed.

This method was called by the JTA-TxManager before the JTA-tx prepare call. Within this method
we prepare odmg for commit and pass all modified persistent objects to DB and release/close the used
connection. We have to close the connection in this method, because the TxManager does prepare for commit
after this method and all used DataSource-connections have to be closed before.

@see javax.transaction.Synchronization