2
我在一家@Stateless
休息資源與Wildfly和MySQL
- 線程A正在讀一
Account
實體上WildFly 9.0.2執行不可重複讀隔離級別不可重複讀隔離級別,打印的平衡然後做一些其他的工作(睡眠)。 - 線程B進來並讀取相同的
Account
實體,打印餘額並通過calculateBalance()
方法計算餘額,然後更新實體。它再次讀取實體並打印出餘額。 - 線程A然後讀取實體並打印出餘額。
根據我對Non-Repeatable讀取級別的理解,線程B應該阻塞直到線程A完成完成(退出事務/無狀態休息資源)。
這裏是打印輸出:
- 線程A:printBalance = 500
- 線程B:printBalance = 500
- 線程B:printBalance = 600
- 線程A:printBalance = 500
從那我可以看到線程B不阻塞,即使線程A仍然忙,也可以運行。
下面是代碼:
@GET
@Path("/{accountId}/{threadName}")
public Response calculcateBalance(@PathParam("accountId") Long accountId, @PathParam("threadName") String threadName) {
Account account = em.find(Account.class, accountId);
printBalance(account,threadName);
if ("ThreadA".equals(threadName)) {
sleepSeconds(10);
} else if ("ThreadB".equals(threadName)) {
account.calculateBalance();
em.merge(account);
}
account = em.find(Account.class, accountId);
printBalance(account,threadName);
return Response.ok().build();
}
如果我更改隔離級別爲序列的所有塊。
我對不可重複讀的理解是否錯誤?在線程A完成之前線程B是否被阻塞?
嗨弗拉德,我認爲這正是發生的事情。我正在連接到一個MySQL數據庫。因此,爲了檢測實體是否發生了變化,我需要在Account實體上添加'@ Version'? – Rentius2407
對於讀取已提交,這是正確的。對於可重複讀取,缺省更新將被檢測到。無論如何,即使在[多請求邏輯事務](http://vladmihalcea.com/2014/09/22/preventing-lost-updates-in-long-conversations/)中,樂觀鎖定也能檢測到丟失的更新。 –
我需要MySQL上的任何配置來檢測它嗎?我不認爲它正在檢測丟失的更新。 – Rentius2407