How to get the transaction Status from HibernateTransactionManager

4.8k views Asked by At

I am trying to upgrade my spring transaction manager from JtaTransactionManager to HibernateTransactionManager. In JTA TransactionManager we have one method which gives the status of current transaction. Based on the status we are doing some operations. The implementation is as follows :

private void checkTransactionStatus(TransactionStatus status){
             if(status instanceof DefaultTransactionStatus) {
                DefaultTransactionStatus transactionStatus = (DefaultTransactionStatus) status;
                if(transactionStatus.getTransaction() instanceof JtaTransactionObject){
                    JtaTransactionObject txObject = (JtaTransactionObject) transactionStatus.getTransaction();
                    int jtaStatus;
                    try {
                        jtaStatus = txObject.getUserTransaction().getStatus();
                        if(jtaStatus==Status.STATUS_MARKED_ROLLBACK){
                            // logic heare
                        }
                    } catch (SystemException e) {}
                }
             }
           }

I want to replace this method with HibernateTransactionManager specific code. I analyzed and found that, HibernateTransactionManager is using HibernateTransactionObject as transaction object. But, unfortunately it's a private inner class that I can't use to get the status. Then I tried to use the parent class JdbcTransactionObjectSupport. But, I don't know how to get the status from this parent class object.

private void checkTransactionStatus(TransactionStatus status){
         if(status instanceof DefaultTransactionStatus) {
            DefaultTransactionStatus transactionStatus = (DefaultTransactionStatus) status;
            if(transactionStatus.getTransaction() instanceof JdbcTransactionObjectSupport){
                JdbcTransactionObjectSupport txObject = (JdbcTransactionObjectSupport) transactionStatus.getTransaction();
                //how to get the current status ?
            }
         }
       }
2

There are 2 answers

0
M. Deinum On BEST ANSWER

Spring has a mechanism for receiving callbacks. You can implement the TransactionSynchronization interface (or easier extend the TransactionSynchronizationAdapter). You probably want to implement the afterCompletion(int) method and put your logic in there.

public class MyTxCallback extends TransactionSynchronizationAdapter {

    public void afterCompletion(int status) {
        if (status==STATUS_ROLLED_BACK) {
            //logic here.
        }
    }

}

You can then bind that to the transaction by calling the TransactionSynchronizationManager when a transaction is started. Now when the transaction is done the method will be called and you can do your logic (regardless of the underlying transactional resource used).

0
Vlad Mihalcea On

If you use HibernateTransactionManager you can get the current transaction state from the Hibernate Session:

LocalStatus status = session.getTransaction().getLocalStatus();

and the LocalStatus has the following states:

public enum LocalStatus {
    /**
     * The local transaction has not yet been begun
     */
    NOT_ACTIVE,
    /**
     * The local transaction has been begun, but not yet completed.
     */
    ACTIVE,
    /**
     * The local transaction has been competed successfully.
     */
    COMMITTED,
    /**
     * The local transaction has been rolled back.
     */
    ROLLED_BACK,
    /**
     * The local transaction attempted to commit, but failed.
     */
    FAILED_COMMIT
}