Java Hibernate save()和事务回滚

Java Hibernate save()和事务回滚,java,mysql,hibernate,orm,transactions,Java,Mysql,Hibernate,Orm,Transactions,在Hibernate中,当我save()事务中的一个对象,然后我回滚它时,保存的对象仍然保留在数据库中。这很奇怪,因为这个问题不是在update()或delete()方法中发生的,而是在save() 以下是我正在使用的代码: DbEntity dbEntity = getDbEntity(); HibernateUtil.beginTransaction(); Session session = HibernateUtil.getCurrentSession(); session.save(db

在Hibernate中,当我
save()
事务中的一个对象,然后我回滚它时,保存的对象仍然保留在数据库中。这很奇怪,因为这个问题不是在
update()
delete()
方法中发生的,而是在
save()

以下是我正在使用的代码:

DbEntity dbEntity = getDbEntity();
HibernateUtil.beginTransaction();
Session session = HibernateUtil.getCurrentSession();
session.save(dbEntity);
HibernateUtil.rollbackTransaction();
下面是HibernateUtil类(仅涉及函数,我保证
getSessionFactory()
方法工作良好-有一个拦截器处理程序,但现在不重要了):

private static final ThreadLocal threadSession=new ThreadLocal();
私有静态final ThreadLocal threadTransaction=new ThreadLocal();
/**
*检索线程本地的当前会话。
*

*如果没有打开会话,则为正在运行的线程打开一个新会话。 * *@返回会话 */ 公共静态会话getCurrentSession() 抛出冬眠异常{ 会话s=(会话)threadSession.get(); 试一试{ 如果(s==null){ debug(“正在为此线程打开新会话”); if(getInterceptor()!=null){ 调试(“使用拦截器:+getInterceptor().getClass()); s=getSessionFactory().openSession(getInterceptor()); }否则{ s=getSessionFactory().openSession(); } threadSession.set(个); } }捕获(HibernateeException例外){ 抛出新的HibernateException(ex); } 返回s; } /** *启动一个新的数据库事务。 */ 公共静态void beginTransaction() 抛出冬眠异常{ 事务tx=(事务)threadTransaction.get(); 试一试{ 如果(tx==null){ debug(“在此线程中启动新的数据库事务”); tx=getCurrentSession().beginTransaction(); threadTransaction.set(tx); } }捕获(HibernateeException例外){ 抛出新的HibernateException(ex); } } /** *回滚数据库事务。 */ 公共静态无效回滚事务() 抛出冬眠异常{ 事务tx=(事务)threadTransaction.get(); 试一试{ threadTransaction.set(null); 如果(tx!=null&&!tx.wasCommitted()&&&!tx.wasrollledback()){ debug(“回滚此线程的数据库事务。”); tx.回滚(); } }捕获(HibernateeException例外){ 抛出新的HibernateException(ex); }最后{ closeSession(); } }


谢谢

检查您的数据库是否支持回滚,即如果您使用的是InnoDB表而不是MyISAM(您可以混合使用事务表和非事务表,但在大多数情况下,您希望所有表都是InnoDB)

MySQL默认使用MyIsam存储引擎。由于MyISAM不支持事务,insert、update和delete语句直接写入数据库。将忽略commit和rollback语句

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

altertable\u name引擎=InnoDB


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

jdbc连接上的autocommit是否设置为false?是(false)。会话的刷新模式为提交模式。@Marcos Ok。谢谢你的反馈。我没有发现你在使用MySQL,我已经相应地更新了我的答案。现在,MySQL的默认引擎是InnoDB。
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();
    }
}