簡體   English   中英

Hibernate save()和事務回滾

[英]Hibernate save() and transaction rollback

在Hibernate中,當我在事務中save()一個對象,然后我回滾它時,保存的對象仍然保留在數據庫中。 這很奇怪,因為update()delete()方法不會發生這個問題,只需使用save()

這是我正在使用的代碼:

DbEntity dbEntity = getDbEntity();
HibernateUtil.beginTransaction();
Session session = HibernateUtil.getCurrentSession();
session.save(dbEntity);
HibernateUtil.rollbackTransaction();

這里是HibernateUtil類(只涉及函數,我保證getSessionFactory()方法運行良好 - 有一個Interceptor處理程序,但它現在無關緊要):

private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();

/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getCurrentSession()
    throws HibernateException {
    Session s = (Session) threadSession.get();
    try {
        if (s == null) {
            log.debug("Opening new Session for this thread.");
            if (getInterceptor() != null) {
                log.debug("Using interceptor: " + getInterceptor().getClass());
                s = getSessionFactory().openSession(getInterceptor());
            } else {
                s = getSessionFactory().openSession();
            }
            threadSession.set(s);
        }
    } catch (HibernateException ex) {
        throw new HibernateException(ex);
    }
    return s;
}

/**
* Start a new database transaction.
*/
public static void beginTransaction()
    throws HibernateException {
    Transaction tx = (Transaction) threadTransaction.get();
    try {
        if (tx == null) {
            log.debug("Starting new database transaction in this thread.");
            tx = getCurrentSession().beginTransaction();
            threadTransaction.set(tx);
        }
    } catch (HibernateException ex) {
        throw new HibernateException(ex);
    }
}

/**
 * Rollback the database transaction.
 */
public static void rollbackTransaction()
    throws HibernateException {
    Transaction tx = (Transaction) threadTransaction.get();
    try {
        threadTransaction.set(null);
        if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
            log.debug("Tyring to rollback database transaction of this thread.");
            tx.rollback();
        }
    } catch (HibernateException ex) {
        throw new HibernateException(ex);
    } finally {
        closeSession();
    }
}

謝謝

檢查您的數據庫是否支持回滾,即如果您使用的是InnoDB表而不是MyISAM(您可以混合使用事務性表和非事務性表,但在大多數情況下,您希望所有表都是InnoDB)。

MySQL默認使用MyIsam存儲引擎。 由於MyISAM不支持事務,因此insert,update和delete語句直接寫入數據庫。 提交和回滾語句將被忽略。

要使用事務,您需要更改表的存儲引擎。 使用此命令:

ALTER TABLE table_name ENGINE = InnoDB;

(請注意,兩個存儲引擎是不同的,如果它仍然按預期運行,您需要測試您的應用程序)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM