JPA Query javadoc(参见http://docs.oracle.com/javaee/6/api/javax/persistence/Query.html#executeUpdate())说
int executeUpdate() Execute an update or delete statement.
Returns: the number of entities updated or deleted
Throws:
IllegalStateException - if called for a Java Persistence query language SELECT statement or for a criteria query
TransactionRequiredException - if there is no transaction
QueryTimeoutException - if the statement execution exceeds
the query timeout value set and only the statement is rolled back
PersistenceException - if the query execution exceeds
the query timeout value set and the transaction is rolled back
回滚州政府和交易之间的区别是什么?我的意思是,回滚事务非常明显,它会将事务设置为回滚并且所有操作都将被撤消。但是如果该语句被回滚(因为它是一个更新/删除/插入操作),那么在这种情况下,整个事务也会被回滚吗?
这个QueryTimeoutException是否被设计为被捕获并允许用户在超时时重试而不影响事务?
答案 0 :(得分:3)
当查询超时且仅回滚语句时,持久性提供程序抛出[QueryTimeoutException]。当前事务(如果一个处于活动状态)将不会标记为回滚。 [QueryTimeoutException]
QueryTimeoutException是PersistenceException的特化。
发生问题时,持久性提供程序抛出[p> PersistenceException]。 PersistenceException 的所有实例(NoResultException,NonUniqueResultException,LockTimeoutException和QueryTimeoutException 的实例除外)将导致当前事务(如果其中一个处于活动状态且已连接到持久性上下文)被标记为回滚。 [PersistenceException]
因此,如果查询超时并不重要,默认情况下它不会导致事务回滚。这就是为什么你必须明确地做到这一点。例如,如果要回滚事务,无论PersistenceException
发生了什么。
catch(PersistenceException e) { ... tx.rollback(); ... }
但有时候即使声明不成功并且发生QueryTimeoutException
,继续交易也是有意义的。
示例场景是在执行仅持久存储额外日志记录的语句期间超时。根据您的使用情况,执行日志语句的时间可能不是很关键,否则,如果核心业务流程(例如持久化订单超时)则至关重要。因此,您不希望失败的日志语句会影响订单的持久性。另一方面,如果订单的持久性失败,则应该滚动备份日志记录的持久性。因此,您始终可以决定哪个查询超时应该导致回滚。
一个示意性的例子是
...
try {
...
queryNonCritical.execute(...);
}
catch(QueryTimeoutException e) {
// not critical move on
...
}
...
try {
...
queryCritical.execute(...);
}
catch(QueryTimeoutException e) {
...
tx.rollback();
...
}
...