Hibernate save() 和事务回滚

Posted

技术标签:

【中文标题】Hibernate save() 和事务回滚【英文标题】:Hibernate save() and transaction rollback 【发布时间】:2011-02-06 00:42:17 【问题描述】:

在 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<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();
    

谢谢

【问题讨论】:

jdbc 连接上的自动提交是否设置为 false? 是的(false)。会话的刷新模式处于 COMMIT 模式。 【参考方案1】:

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

【讨论】:

@Marcos 好的。感谢您的反馈。我没有发现你在使用 mysql,我已经相应地更新了我的答案。【参考方案2】:

MySQL 默认使用 MyIsam 存储引擎。由于 MyISAM 不支持事务,因此插入、更新和删除语句直接写入数据库。提交和回滚语句被忽略。

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

ALTER TABLE table_name ENGINE = InnoDB;

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

【讨论】:

一段时间以来,MySQL的默认引擎是InnoDB。

以上是关于Hibernate save() 和事务回滚的主要内容,如果未能解决你的问题,请参考以下文章

hibernate配置事务,运用在service层,那么在serviceImpl中的异常要怎么处理?

Hibernate 事务提交和事务回滚

hibernate的save不执行

spring 事务回滚

Spring 实现部分事务回滚

spring管理事务回滚