我需要寫鎖定一個父實體,而我正在與他的子實體,以不允許修改(或earse)的父母。 我需要使用Spring來執行此操作,並直接從數據庫執行鎖定(以避免在集羣中執行應用程序時出現問題)。從數據庫中寫入鎖實體在彈簧
1
A
回答
9
爲了實現你正在尋找的策略,你將需要火父排SELECT FOR UPDATE
SQL查詢(例如,SELECT * FROM parent WHERE id = ? FOR UPDATE
,這獲得由SELECT
查詢獲取的行上的鎖。
總體戰略
- 開始事務。
- 裝入父行與
SELECT FOR UPDATE
。 - 更新孩子。
- 保存孩子。
- 提交交易。這將保存子項並釋放父行上的鎖。
您可以使用Spring事務來強制執行事務邊界。像下面的內容將工作:
class SomeService {
@Transactional
public ... someMethod(...) {
// Load the parent row using SELECT FOR UPDATE.
// Save children.
}
}
@Transactional
將申請事務語義各地調用someMethod
。請注意,該方法必須爲public
才能運作@Transactional
。
執行一個SELECT FOR UPDATE
取決於你究竟是如何訪問數據庫 - 春天JDBC,ORM春天,春天JPA的數據,等等。這裏是你將如何使用這些庫來實現這一目標:
春天JDBC
您可以使用JdbcTemplate
類簡單地執行SELECT FOR UPDATE
查詢。 jdbcTemplate.execute("SELECT * FROM parent WHERE row = ? FOR UPDATE")
應該工作。
春ORM
你將不得不使用特定的ORM模板類強制執行鎖定模式。例如,使用Hibernate4 HibernateTemplate
可以使用hibernateTemplate.get(Class<T> entityType, Serializable id, LockMode lock)
。
春數據JPA
您可以標註信息庫法@Lock(LockModeType.PESSIMISTIC_WRITE)
執行查詢時強制執行悲觀鎖。例如
interface ParentRepository extends CrudRepository<Parent, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Parent findOne(Long id);
}
會完成這項工作。你應該小心
的一件事是,如果這種操作稱爲併發的次數太多,你會體驗到超時和可能出現的死鎖,因爲行被完全鎖定。記住以下事項會使您受益:
- 保持鎖只有很短的時間,可能是在處理的最後階段,確保任何驗證等都是預先執行的。這將確保鎖被快速釋放。
- 對併發用戶進行測試,並瞭解出現超時和死鎖的頻率。如果您看到超時和死鎖,並且不希望用戶重試,則可以使用Spring Retry項目提供的功能重試方法。
相關問題
- 1. 彈簧數據鎖定
- 2. 彈簧數據和鎖定
- 3. 在兩個數據庫中寫入彈簧雲流
- 4. 彈簧數據JPA不刪除實體
- 5. 彈簧數據Envers庫未能注入
- 6. 彈簧數據存儲庫(JPA) - 使用實體關係的findByXXX
- 7. 如何使用彈簧數據保存實體的子實體
- 8. 在彈簧數據實體中填充「已創建」列
- 9. 如何在彈簧數據中觸發實體更新?
- 10. 彈簧數據庫重用
- 11. Pagingandsortingrepositrory在彈簧數據,在該實體的主鍵不
- 12. 彈簧數據庫中的JPA繼承
- 13. 彈簧連接在Postgres數據庫
- 14. 在內存數據庫休眠彈簧
- 15. 彈簧數據中的收集實體上的鏈接REST
- 16. 不同包中的彈簧數據實體
- 17. 彈簧實體併發控制,同時堅持到數據庫中
- 18. 在彈簧中從數據庫填充下拉列表
- 19. 使用彈簧數據不能在視圖中訪問的數據庫數據使用彈簧數據的JPA
- 20. 彈出窗體可以在數據庫中插入數據
- 21. 彈簧靴,彈簧安全鏈接數據庫
- 22. 實體框架寫入鎖定選擇
- 23. 用zookeeper實現對數據庫的寫入鎖定?
- 24. 從LINQ在C#中寫入數據庫
- 25. 彈簧批量彈簧數據
- 26. 如何在活動彈簧事務中將數據刷入數據庫?
- 27. 彈簧數據與實體關聯問題
- 28. 彈簧數據的JPA:保存新的實體引用現有
- 29. 彈簧數據:與Java配置未知實體
- 30. 彈簧數據detchated實體子對象上