该方法具有@Transactional注释时,我是否必须调用entityManager.flush()
还是在退出时自动写入数据?
另外,如果我两次调用它,是否总是会出现无交易异常?
@PersistenceContext(unitName = "CONFIGURATION", type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
@Transactional
public boolean generate() {
doStuffToDatabase();
//entitymanager.flush();
//entitymanager.flush(); //If I call it twice do I always get a no transaction exception?
}
答案 0 :(得分:1)
更改事务内的实体时,实际上并没有更改数据库,而是更改了行的内存模型。提交事务后,对内存中模型的更改将刷新到数据库,这意味着将执行将数据库状态恢复为模型状态所需的SQL查询。
手动调用entityManager.flush时,您要做的就是在事务完成之前同步这些更改。这有一些含义:
通常,不需要进行手动冲洗。我唯一能看到的实际收益是我的第二点,如果存在约束违例,必须立即停止执行。但是在我看来,这是一种代码味道,应该通过了解您可以做和不能做的更改以及正确的事务设置来轻松避免。
第二次调用flush,而在这之间没有任何更改,则不会产生任何效果,因为已经对数据库进行了所有更改。
答案 1 :(得分:1)
@Transactional
方法成功完成后,它将提交事务。在提交事务之前,如果未显式调用它,它将自动在后台调用flush()
。
flush()
将立即导致JPA发出SQL来插入或更新相关数据库记录,如果持久性上下文中有任何未决的更改。第一次刷新后立即再次调用刷新是没有意义的,因为持久性上下文中所有未决的更改已在第一次刷新中更新到数据库。
通常,当我们需要更新大量记录以防止服务器内存不足时,我们通常手动调用flush()
。这个想法是,在对某些记录批次进行更改之后,我们刷新并清除持久性上下文,然后继续处理其他批次。