我正在使用带有@Transactional
批注的事务方法。我正在尝试使用JpaRepository的save()方法将对象保存到数据库。 (由于数据库关系的限制,这将引发错误。)
现在,当我调试程序时,我发现在事务方法的末尾引发了异常,而不是在调用save
方法时引发了异常。这与非事务方法的行为完全不同。
有人可以解释为什么吗?为什么在事务方法的末尾抛出异常,而不是在实际发生时抛出该异常。
我的第二个问题是,当方法为Transactional时,抛出的异常为DataViolationException
,而当它为非事务性时,抛出的异常为PSQLException
(使用Postgres数据库)。为什么呢?
下面是代码
@Transactional
public ResponseType methodA(UserObject userObject) {
//save call
jpaRepoObject.save(userObject);
//next call will fail due to relational constraints on database
jpaRepoObject.save(userObject); //should throw PSQLException/DataViolationException
return new ResponseType("success"); //Error thrown after this line.
}
答案 0 :(得分:0)
save
doesn't immediately flush data to underlying database. First, entities are saved into first level cache, and, when time to flush come(at the end of transaction - like in your case, or when a query is issued), only then entities are saved into database.
To see behaviour which you expect, use saveAndFlush
method.
答案 1 :(得分:0)
这是JPA的一项功能,称为事务后写。您的代码正在执行的所有插入和更新都将由Jpa实现进行存储,直到刷新事务为止。这使jpa实现可以对这些操作进行重新排序,以最合理的顺序进行。
刷新意味着执行到目前为止由entityManager实例存储的所有动作。您可以告诉entityManager刷新,或者一旦达到事务边界,它将自动刷新。
当您插入实体并且需要为其生成ID以便可以稍后以相同方法使用它时,显式刷新的示例。
您始终可以在事务中运行sql并在以后提交或回滚。刷新会运行sql,但不会提交。