Hibernate save()和事务回滚

Mar*_*ark 9 java mysql orm hibernate transactions

在Hibernate中,当我save()是事务中的对象,然后我回滚它时,保存的对象仍然保留在DB中.这很奇怪,因为这个问题不会发生在update()delete()方法上,只是用save().

这是我正在使用的代码:

DbEntity dbEntity = getDbEntity();
HibernateUtil.beginTransaction();
Session session = HibernateUtil.getCurrentSession();
session.save(dbEntity);
HibernateUtil.rollbackTransaction();
Run Code Online (Sandbox Code Playgroud)

这里是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Pas*_*ent 8

检查你的数据库支持回滚也就是说,如果你正在使用InnoDB表,而不是MyISAM的(你可以混合事务性和非事务表,但在大多数情况下,你希望所有的表是InnoDB的).


Kde*_*per 5

MySQL默认使用MyIsam存储引擎.由于MyISAM不支持事务,因此insert,update和delete语句直接写入数据库.提交和回滚语句将被忽略.

要使用事务,您需要更改表的存储引擎.使用此命令:

ALTER TABLE table_name ENGINE = InnoDB;

(请注意,两个存储引擎是不同的,如果它仍然按预期运行,则需要测试您的应用程序)

  • 一段时间以来,MySQL的默认引擎是InnoDB. (4认同)