首页 > 解决方案 > 为什么休眠在没有事务的情况下保存值?

问题描述

我正在使用带有休眠(5.3.9)的弹簧靴(2.1.4)。

public class BaseDao{

@Autowired 
private SessionFactory sessionFactory;

private Session session;
private Transaction transaction;

@Autowired
private EntityManagerFactory entityManagerFactory;

@PersistenceContext
private EntityManager entityManager; 

public SessionFactory getSessionFactory() {
    return sessionFactory;
}

public EntityManagerFactory getEntityManagerFactory() {
    return entityManagerFactory;
}

public EntityManager getEntityManager() {
    return entityManager;
}


public Session getSession() throws Exception{
    if(session == null) {
        session = getSessionFactory().openSession();
    }
    
    if(transaction == null) {
        transaction = session.beginTransaction();
    }
    return session;
}

public void commit() throws Exception{
    if(transaction != null) {
        transaction.commit();
        transaction = null;
    }
    
    if(session != null) {
        session.close();
        session = null;
    }
}

public void rollback() throws Exception{
    if(transaction != null) {
        transaction.rollback();
        transaction = null;
    }

    if(session != null) {
        session.close();
        session = null;
    }
}

protected void save(Object object) throws Exception {
    getSessionFactory().openSession().save(object);    //saves data in db 
    getSession().save(object);    //is not saving data
}   

getSessionFactory().openSession().save(object); 即使没有提交getSession().save(object);此代码也将数据保存到数据库 ;此代码需要在创建 txn 但未提交时调用提交

休眠日志

我在下面的日志中看到了这两行代码

插入 TEST_ENTITY (CREATED_BY, CREATED_DATE, ENABLED, LAST_MODIFIED_BY, LAST_MODIFIED_DATE, NAME) 值 (?, ?, ?, ?, ?, ?)

我对这种行为没有几个问题。

  1. 我知道没有提交就不会发生写操作,所以知道这里有什么问题或在第一种情况下导致提交的原因是什么?

  2. 可以使用上面的代码,即第一个场景吗?

  3. 如果第一种方法不正确,那么我是否需要为每个对象创建并提交 txn,任何更好的方法,这样即使我必须提交 txn,我也不想在每个新方法中复制 txn.commit()写在 BaseDao.java 中,即说我有 create()、update()、delete() 方法我可以把这个 txn.commit() 移出方法吗?

  4. 很少有地方我使用 spring data jpa 来获取/保存记录(如下所示),在 spring data jpa 中如何处理 txn?任何参考?

    @Repository 公共接口 TestEntitytRepo 扩展 JpaRepository<TestEntity, Long> { ... }

如果我错过了要在此处捕获的任何详细信息,请告诉我。

提前致谢。

标签: spring-boothibernatespring-data-jpaspring-datahibernate-session

解决方案


在 hibernate 中,Save() 方法将对象存储到数据库中。它将持久化给定的瞬态实例,首先分配一个生成的标识符。它返回创建的实体的 id。当使用 SessionFactory.openSession() 创建 hibernate 中的会话时,不会创建任何事务,因此所有操作都在事务上下文之外执行!为了确保将数据保存到数据库中,需要创建一个新事务。

我对你上面解释的行为有点怀疑。似乎启用了自动提交选项。如果是这样,那么这不是问题,因为 save() 方法已完成,后台自动提交!


推荐阅读