2013-03-05 66 views
1

我收集了一些關於我的系統的日統計數據,比方說,使用我係統的人數和他們今天花費的總時間。我的統計實體是這樣的:根據以前的值原子插入或更新實體

class Stats { 
    Date date; 
    Long numUsers; 
    Long totalTime;   
} 

白天我需要更新這些統計基於先前值,如:

stats.numUsers += 1; 
stats.totalTime += timeSpentByLastUser; 

當然,如果這是第一次對於今天,我需要初始化這些數據:

stats.numUsers = 1; 
stats.totalTime = timSpentByFirstUserForToday; 

現在我想將全部移到數據庫。也就是說,使Stats成爲一個實體並根據先前的值進行原子插入/更新。那麼,我該如何做到這一點?我正在使用JPA,因此適合其型號的任何解決方案都將適用。

請注意,JPA具有插入或更新機制 - EntityManager.merge() - 但它沒有考慮實體的先前狀態,這在此處是必需的。

+0

如果DB是ACID則交易已經原子,所有你需要的要做的是[鎖定數據](http://city81.blogspot.co.uk/2011/03/pessimistic-and-optimistic-locking-in.html)。 – 2013-03-05 14:15:14

+0

目前我們使用2個保存ACID屬性的數據庫,但它可能會改變,所以我正在尋找一個基於JPA的解決方案(我假定JPA並不保證底層數據庫始終保持ACID)。 – ffriend 2013-03-05 14:25:34

回答

3

是的,你保持原子性,通過強制用於持久化的事務鎖定機制。

Employee employee = entityManager.find(Employee.class, id); 
employee.getAddress().setCity("Ottawa"); 
entityManager.lock(employee, LockModeType.WRITE); 

請參考下面的鏈接,它提供了JPA可用的鎖模式2.0

JPA 2.0 Locking