2017-09-24 64 views
0

我正在開發一個運行在具有MySQL的WildFly 8上的EJB 3應用程序。我需要更新實體(User)中的計數器(receiptCounter),並決定嘗試使用存儲過程調用以避免競爭條件。WildFly在MySQL中不存儲存儲過程調用

這是我創建的存儲過程:

DELIMITER $$ 
CREATE PROCEDURE increment_receipt_counter 
(
    IN userID_in INT 
) 
BEGIN 
    UPDATE User SET receiptCounter = receiptCounter + 1 WHERE id = userID_in; 
    SELECT receiptCounter AS receiptCounter_new FROM User WHERE id = userID_in; 
END 
$$ 
DELIMITER ; 

這是我怎麼稱呼它:

import javax.persistence.EntityManager; 
import javax.persistence.StoredProcedureQuery; 
... 
public int incrementReceiptsCounter(int userID) throws InvalidEntityException, UnauthorizedException 
{ 
    StoredProcedureQuery q = entityManager.createStoredProcedureQuery("increment_receipt_counter"); 
    q.registerStoredProcedureParameter("userID_in", Integer.class, ParameterMode.IN); 
    q.setParameter("userID_in", userID); 
    q.executeUpdate(); 
    return (Integer)q.getSingleResult(); 
} 

奇怪的是:從Java調用,程序返回正確的新計數器值,但新值不會持久保存在數據庫中。例如,如果在調用過程之前,數據庫中的receiptCounter爲1,則Java中的過程調用將返回2,但數據庫中的User表仍顯示值1.當我直接從MySQL命令行調用過程時,它工作得很好。我究竟做錯了什麼?

+0

缺失的提交? – Shadow

回答

0

在mysql命令行auto commit可能啓用意味着您的更新是自動保存的。

在java連接中,您可能禁用了auto commit,因此更新未提交,但在與update相同的事務中運行的select仍然返回更新後的值。

但是,如果要處理併發性,則應首先使用select ... for update鎖定計數器,然後更新該值。

+0

只是關於交易的一個說明,如果他使用用戶管理的交易,那麼這種情況就會發生。如果他使用容器管理的事務,則應該自動調用自動提交,並且問題可能在其他地方 – maress