我有一個從數據庫讀取的Spring事務,如果找不到它,它會創建它。例如:如何讓兩個完全相同的讀寫併發事務等待對方?
@Transactional
public int getUserIdCreateIfNotExistent(String email) throws Exception {
try {
return jdbcTemplate.queryForObject("SELECT id FROM users WHERE email = ?", Integer.class, email);
} catch (IncorrectResultSizeDataAccessException e) {
Thread.sleep(10000);
return jdbcTemplate.queryForObject("INSERT INTO users (email) values(?) RETURNING id", Integer.class, email);
}
}
當這個方法被調用兩次的同時,將在具有兩個不同的用戶在數據庫相同的電子郵件的結果(有獨特的電子郵件沒有限制,這只是爲了演示)。
我希望第二個事務等待第一個事務,以便只創建一個用戶。我試着將事務隔離級別更改爲Isolation.SERIALIZABLE
,但它所做的只是使提交最後一次回滾的事務。
編輯: 之前有人建議使用或類似的東西鎖定的Java解決方案,是要明白,這個方法是一個Web應用程序的一部分,在特定端點被擊中稱爲是非常重要的。該Web應用程序在多個不同的計算機上運行,並且負載平衡,並且在端點被同時調用兩次時發生問題。這意味着代碼可能在兩臺不同的計算機上並行執行,與另一臺計算機上的同一個數據庫對話。
隔離級別不會幫助,因爲你插入新行。除非遇到獨特的限制。 –