mirror of
https://github.com/Vonng/ddia.git
synced 2024-12-06 15:20:12 +08:00
update the translation of eggs
This commit is contained in:
parent
9ab48749ed
commit
cec8b0dc4a
4
ch5.md
4
ch5.md
@ -654,8 +654,8 @@ LWW 实现了最终收敛的目标,但以 **持久性** 为代价:如果同
|
||||
|
||||
1. 客户端 1 将牛奶加入购物车。这是该键的第一次写入,服务器成功存储了它并为其分配版本号 1,最后将值与版本号一起回送给客户端。
|
||||
2. 客户端 2 将鸡蛋加入购物车,不知道客户端 1 同时添加了牛奶(客户端 2 认为它的鸡蛋是购物车中的唯一物品)。服务器为此写入分配版本号 2,并将鸡蛋和牛奶存储为两个单独的值。然后它将这两个值 **都** 返回给客户端 2 ,并附上版本号 2。
|
||||
3. 客户端 1 不知道客户端 2 的写入,想要将面粉加入购物车,因此认为当前的购物车内容应该是 [牛奶,面粉]。它将此值与服务器先前向客户端 1 提供的版本号 1 一起发送到服务器。服务器可以从版本号中知道 [牛奶,面粉] 的写入取代了 [牛奶] 的先前值,但与 [鸡蛋] 的值是 **并发** 的。因此,服务器将版本号 3 分配给 [牛奶,面粉],覆盖版本 1 的值 [牛奶],但保留版本 2 的值 [蛋],并将所有的值返回给客户端 1。
|
||||
4. 同时,客户端 2 想要加入火腿,不知道客户端 1 刚刚加了面粉。客户端 2 在最近一次响应中从服务器收到了两个值 [牛奶] 和 [蛋],所以客户端 2 现在合并这些值,并添加火腿形成一个新的值 [鸡蛋,牛奶,火腿]。它将这个值发送到服务器,带着之前的版本号 2 。服务器检测到新值会覆盖版本 2 的值 [鸡蛋],但新值也会与版本 3 的值 [牛奶,面粉] **并发**,所以剩下的两个值是版本 3 的 [牛奶,面粉],和版本 4 的 [鸡蛋,牛奶,火腿]。
|
||||
3. 客户端 1 不知道客户端 2 的写入,想要将面粉加入购物车,因此认为当前的购物车内容应该是 [牛奶,面粉]。它将此值与服务器先前向客户端 1 提供的版本号 1 一起发送到服务器。服务器可以从版本号中知道 [牛奶,面粉] 的写入取代了 [牛奶] 的先前值,但与 [鸡蛋] 的值是 **并发** 的。因此,服务器将版本号 3 分配给 [牛奶,面粉],覆盖版本 1 的值 [牛奶],但保留版本 2 的值 [鸡蛋],并将所有的值返回给客户端 1。
|
||||
4. 同时,客户端 2 想要加入火腿,不知道客户端 1 刚刚加了面粉。客户端 2 在最近一次响应中从服务器收到了两个值 [牛奶] 和 [鸡蛋],所以客户端 2 现在合并这些值,并添加火腿形成一个新的值 [鸡蛋,牛奶,火腿]。它将这个值发送到服务器,带着之前的版本号 2 。服务器检测到新值会覆盖版本 2 的值 [鸡蛋],但新值也会与版本 3 的值 [牛奶,面粉] **并发**,所以剩下的两个值是版本 3 的 [牛奶,面粉],和版本 4 的 [鸡蛋,牛奶,火腿]。
|
||||
5. 最后,客户端 1 想要加培根。它之前从服务器接收到了版本 3 的 [牛奶,面粉] 和 [鸡蛋],所以它合并这些,添加培根,并将最终值 [牛奶,面粉,鸡蛋,培根] 连同版本号 3 发往服务器。这会覆盖版本 3 的值 [牛奶,面粉](请注意 [鸡蛋] 已经在上一步被覆盖),但与版本 4 的值 [鸡蛋,牛奶,火腿] 并发,所以服务器将保留这两个并发值。
|
||||
|
||||
![](img/fig5-13.png)
|
||||
|
@ -654,8 +654,8 @@ LWW 實現了最終收斂的目標,但以 **永續性** 為代價:如果同
|
||||
|
||||
1. 客戶端 1 將牛奶加入購物車。這是該鍵的第一次寫入,伺服器成功儲存了它併為其分配版本號 1,最後將值與版本號一起回送給客戶端。
|
||||
2. 客戶端 2 將雞蛋加入購物車,不知道客戶端 1 同時添加了牛奶(客戶端 2 認為它的雞蛋是購物車中的唯一物品)。伺服器為此寫入分配版本號 2,並將雞蛋和牛奶儲存為兩個單獨的值。然後它將這兩個值 **都** 返回給客戶端 2 ,並附上版本號 2。
|
||||
3. 客戶端 1 不知道客戶端 2 的寫入,想要將麵粉加入購物車,因此認為當前的購物車內容應該是 [牛奶,麵粉]。它將此值與伺服器先前向客戶端 1 提供的版本號 1 一起傳送到伺服器。伺服器可以從版本號中知道 [牛奶,麵粉] 的寫入取代了 [牛奶] 的先前值,但與 [雞蛋] 的值是 **併發** 的。因此,伺服器將版本號 3 分配給 [牛奶,麵粉],覆蓋版本 1 的值 [牛奶],但保留版本 2 的值 [蛋],並將所有的值返回給客戶端 1。
|
||||
4. 同時,客戶端 2 想要加入火腿,不知道客戶端 1 剛剛加了麵粉。客戶端 2 在最近一次響應中從伺服器收到了兩個值 [牛奶] 和 [蛋],所以客戶端 2 現在合併這些值,並新增火腿形成一個新的值 [雞蛋,牛奶,火腿]。它將這個值傳送到伺服器,帶著之前的版本號 2 。伺服器檢測到新值會覆蓋版本 2 的值 [雞蛋],但新值也會與版本 3 的值 [牛奶,麵粉] **併發**,所以剩下的兩個值是版本 3 的 [牛奶,麵粉],和版本 4 的 [雞蛋,牛奶,火腿]。
|
||||
3. 客戶端 1 不知道客戶端 2 的寫入,想要將麵粉加入購物車,因此認為當前的購物車內容應該是 [牛奶,麵粉]。它將此值與伺服器先前向客戶端 1 提供的版本號 1 一起傳送到伺服器。伺服器可以從版本號中知道 [牛奶,麵粉] 的寫入取代了 [牛奶] 的先前值,但與 [雞蛋] 的值是 **併發** 的。因此,伺服器將版本號 3 分配給 [牛奶,麵粉],覆蓋版本 1 的值 [牛奶],但保留版本 2 的值 [雞蛋],並將所有的值返回給客戶端 1。
|
||||
4. 同時,客戶端 2 想要加入火腿,不知道客戶端 1 剛剛加了麵粉。客戶端 2 在最近一次響應中從伺服器收到了兩個值 [牛奶] 和 [雞蛋],所以客戶端 2 現在合併這些值,並新增火腿形成一個新的值 [雞蛋,牛奶,火腿]。它將這個值傳送到伺服器,帶著之前的版本號 2 。伺服器檢測到新值會覆蓋版本 2 的值 [雞蛋],但新值也會與版本 3 的值 [牛奶,麵粉] **併發**,所以剩下的兩個值是版本 3 的 [牛奶,麵粉],和版本 4 的 [雞蛋,牛奶,火腿]。
|
||||
5. 最後,客戶端 1 想要加培根。它之前從伺服器接收到了版本 3 的 [牛奶,麵粉] 和 [雞蛋],所以它合併這些,新增培根,並將最終值 [牛奶,麵粉,雞蛋,培根] 連同版本號 3 發往伺服器。這會覆蓋版本 3 的值 [牛奶,麵粉](請注意 [雞蛋] 已經在上一步被覆蓋),但與版本 4 的值 [雞蛋,牛奶,火腿] 併發,所以伺服器將保留這兩個併發值。
|
||||
|
||||
![](../img/fig5-13.png)
|
||||
|
@ -258,7 +258,7 @@ SELECT COUNT(*)FROM emails WHERE recipient_id = 2 AND unread_flag = true
|
||||
|
||||
如果兩個事務同時嘗試更新資料庫中的相同物件,會發生什麼情況?我們不知道寫入的順序是怎樣的,但是我們通常認為後面的寫入會覆蓋前面的寫入。
|
||||
|
||||
但是,如果先前的寫入是尚未提交事務的一部分,使得後面的寫入覆蓋了一個尚未提交的值,這時會發生什麼?這被稱作 **髒寫(dirty write)**【28】。在 **讀已提交** 的隔離級別上執行的事務必須防止髒寫,通常是延遲第二次寫入,直到第一次寫入事務提交或中止為止。
|
||||
但是,如果先前的寫入是尚未提交事務的一部分,使得後面的寫入覆蓋了一個尚未提交的值,這時會發生什麼呢?這被稱作 **髒寫(dirty write)**【28】。在 **讀已提交** 的隔離級別上執行的事務必須防止髒寫,通常是延遲第二次寫入,直到第一次寫入事務提交或中止為止。
|
||||
|
||||
透過防止髒寫,這個隔離級別避免了一些併發問題:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user