2014-09-01 44 views
3

您好我正在努力與JPA2的Optimistick鎖,我沒有更多的想法爲什麼會發生。 我的情況是,我正在運行多個線程,但DB中有一個存儲進度的實體。這意味着不同的線程在執行過程中試圖更新這個實體,以便能夠看到用戶的進度。JPA2 Optimistick鎖

我有一個方法addAllItemsaddDone。這兩種方法都用於通過多個線程更新實體,並通過顯示(done/allItems)*100來顯示結果。

方法很簡單,在開始

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void addAllItems(Long id, Integer items){ 
    Job job = jobDao.findById(id); 
    job.setAll(job.getAll() + items); 

    jobDao.merge(job); 
} 

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void addDone(Long id, Integer done){ 
    Job job = jobDao.findById(id); 
    job.setDone(job.getDone() + done); 

    jobDao.merge(job); 
} 

當我意識到樂觀鎖發生我通過增加同步到簽名改成這兩種方法。它沒有效果,所以我添加了刷新(從實體管理器),以確保我有最新版本。它也沒有區別。我還添加了在最後手動沖洗,但還是沒有好...

這裏是方法的最終版本(addAllItems幾乎是一樣的,唯一不同的是在二傳手):

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public synchronized void addDone(Long id, Integer done){ 
    Job job = jobDao.findById(id); 
    job = jobDao.refresh(job); 
    job.setDone(job.getDone() + done); 

    jobDao.merge(job); 
    jobDao.flush(); 
} 

jobDao.refresh方法只是在entityManager上調用刷新。 我正在使用eclipselink 2.40。

我還能檢查什麼? 我目前出來的想法...

+0

我正在努力,但截止日期非常近,所以我正在尋找更有經驗的人的幫助。我認爲這就是創建stackoverflow的原因。如果你不想回答,請不要回復。 – wojtek 2014-09-01 19:56:54

+0

也許你應該在工作中使用悲觀鎖定? – 2014-09-01 22:37:42

+0

錯誤發生在哪個實體上?真的是'工作'?你能否在'Job'中顯示'all'和'done'是什麼 – 2014-09-01 22:48:43

回答

1

正如您確定您正在使用代理服務器(我假設您已正確配置PlatformTransactionManager),您可以嘗試在事務中使用顯式的悲觀鎖 - 通常你不應該需要這樣做,但如果解決了這個問題...

我想,在你的刀,你有這樣的:

Job job = EntityManager.find(Job.class, jobId); 

要強制悲觀鎖,只是改變它到:

Job job = EntityManager.find(Job.class, jobId, LockModeType.PESSIMISTIC_WRITE); 

正如你剛剛加載,修改,存儲和提交,它可能是悲觀鎖定的正確用例。