2016-05-28 55 views
3

JPA查詢的javadoc(見http://docs.oracle.com/javaee/6/api/javax/persistence/Query.html#executeUpdate())說差異回滾語句,並在JPA交易

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 

什麼是回滾statemente和交易之間的區別?我的意思是,回滾事務非常明顯,它會將事務設置爲回滾,並且所有操作都將被撤消。但是,如果語句回滾(因爲它是更新/刪除/插入操作),那麼在這種情況下整個事務是不是也會回滾呢?

這是QueryTimeoutException設計爲被捕獲並允許用戶在超時重試而不影響事務?

+0

不要YOUT仍在尋找答案? –

回答

3

當查詢超時並且只有語句被回滾時,持久化提供程序拋出[QueryTimeoutException]。當前事務(如果有)處於活動狀態時,將不標記爲回滾。 [QueryTimeoutException]

QueryTimeoutExceptionPersistenceException的一個特例。

發生問題時,由持久性提供者拋出[PersistenceException is]。除了NoResultException,NonUniqueResultException,LockTimeoutException和QueryTimeoutException的實例之外,PersistenceException 的所有實例都將導致當前事務(如果有一個活動並且持久化上下文已加入到該實例中)標記爲回滾。 [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(); 
    ... 
} 
...