如何从 HibernateTransactionManager 获取事务状态

How to get the transaction Status from HibernateTransactionManager

我正在尝试将我的 spring 事务管理器从 JtaTransactionManager 升级到 HibernateTransactionManager。在 JTA TransactionManager 中,我们有一种方法可以给出当前事务的状态。根据状态我们正在做一些操作。实现如下:

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) {}
                }
             }
           }

我想用 HibernateTransactionManager 特定代码替换此方法。我分析发现,HibernateTransactionManager使用的是HibernateTransactionObject作为事务对象。但是,不幸的是,它是一个私人内部 class,我无法使用它来获取状态。然后我尝试使用父 class JdbcTransactionObjectSupport。但是,我不知道如何从这个父 class 对象中获取状态。

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 ?
            }
         }
       }

Spring 有一个接收回调的机制。您可以执行 TransactionSynchronization interface (or easier extend the TransactionSynchronizationAdapter)。您可能想要实现 afterCompletion(int) 方法并将您的逻辑放在那里。

public class MyTxCallback extends TransactionSynchronizationAdapter {

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

}

然后您可以在事务启动时通过调用 TransactionSynchronizationManager 将其绑定到事务。现在,当交易完成时,将调用该方法,您可以执行您的逻辑(无论使用的底层交易资源如何)。

如果您使用HibernateTransactionManager,您可以从 Hibernate Session 获取当前事务状态:

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

并且 LocalStatus 具有以下状态:

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
}