簡體   English   中英

樂觀鎖定 - 基於 session 的鎖定

[英]Optimistic locking - session based locking

實際上,我有一個與 Spring/Hibernate 中的樂觀鎖定有關的問題。

我有以下場景,典型的 REST 應用程序和 SQL 數據庫。

  1. 用戶 A 進入頁面並讀取數據 - 實體版本 0 - GET 請求
  2. 用戶 B 進入頁面並讀取數據 - 實體版本 0 - GET 請求
  3. 用戶 A 保存數據 - 實體版本 1 - PUT 請求
  4. 用戶 B 想要保存數據(PUT 請求),但我應該看到樂觀鎖異常

現在我的問題是:hibernate 在哪里保存有關實體版本的數據? 我理解一切都在同一個事務中的情況:

  1. 加載數據
  2. 有人在不同的交易中改變了實體
  3. 保存數據

但在我的情況下,版本將消失 GET 和 PUT 處於完全不同的事務/線程等中。

在我看來,我應該保存用戶加載的某個版本以在 GET 和 PUT 請求之間建立關聯,例如在 HTTP session 中,或者只是在響應中返回版本,然后在 PUT 請求中發送該版本。

可以以更好的方式完成嗎? 像開箱即用?

JPA/Hibernate 在實體定義中有 @Version 列來檢查樂觀或悲觀鎖定。 JPA/Hibernate 將版本保存在表中。 例如,您在數據庫中有 Country 表:

CREATE TABLE country (
  id BIGINT NOT NULL AUTO_INCREMENT,
  version BIGINT DEFAULT 0,
  ...
);

和國家實體:

@Entity
@Table(name = "country")
public class Country implements Serializable {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id", nullable = false)
  private Long id;

  @Version
  @Column(name = "version")
  private Long version;

  ...
}

如果使用樂觀鎖沖突更新國家實體實例,則會在 JPA 中收到 OptimisticLockException。 您不需要管理版本,JPA/Hibernate 會為您檢查實體實例的版本。

不同交易的更新:

在不同的事務中,您也可以獲得 OptimisticLockException,因為 JPA/Hibernate 會在每次更新時使用數據庫表檢查版本列。 只要您保存更改(提交),就會檢查實體版本的另一個更改,無論是在同一事務中還是在不同事務中。 更好的是,您可以使用 Spring 框架中的 @Transactional 注釋來管理您的事務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM