mirror of
https://github.com/Vonng/ddia.git
synced 2024-12-06 15:20:12 +08:00
update zh-tw content
This commit is contained in:
parent
f0d22dc1e8
commit
1101ae5a91
@ -420,8 +420,7 @@ Web 服務僅僅是透過網路進行 API 請求的一系列技術的最新版
|
||||
* 如果你重試失敗的網路請求,可能會發生請求實際上正在透過,只有響應丟失。在這種情況下,重試將導致該操作被執行多次,除非你在協議中引入去重機制(**冪等**,即 idempotence)。本地函式呼叫沒有這個問題。 (在 [第十一章](ch11.md) 更詳細地討論冪等性)
|
||||
* 每次呼叫本地功能時,通常需要大致相同的時間來執行。網路請求比函式呼叫要慢得多,而且其延遲也是非常可變的:好的時候它可能會在不到一毫秒的時間內完成,但是當網路擁塞或者遠端服務超載時,可能需要幾秒鐘的時間完成一樣的東西。
|
||||
* 呼叫本地函式時,可以高效地將引用(指標)傳遞給本地記憶體中的物件。當你發出一個網路請求時,所有這些引數都需要被編碼成可以透過網路傳送的一系列位元組。如果引數是像數字或字串這樣的基本型別倒是沒關係,但是對於較大的物件很快就會變成問題。
|
||||
|
||||
- 客戶端和服務可以用不同的程式語言實現,所以 RPC 框架必須將資料型別從一種語言翻譯成另一種語言。這可能會捅出大簍子,因為不是所有的語言都具有相同的型別 —— 例如回想一下 JavaScript 的數字大於 $2^{53}$ 的問題(請參閱 “[JSON、XML 和二進位制變體](#JSON、XML和二進位制變體)”)。用單一語言編寫的單個程序中不存在此問題。
|
||||
* 客戶端和服務可以用不同的程式語言實現,所以 RPC 框架必須將資料型別從一種語言翻譯成另一種語言。這可能會捅出大簍子,因為不是所有的語言都具有相同的型別 —— 例如回想一下 JavaScript 的數字大於 $2^{53}$ 的問題(請參閱 “[JSON、XML 和二進位制變體](#JSON、XML和二進位制變體)”)。用單一語言編寫的單個程序中不存在此問題。
|
||||
|
||||
所有這些因素意味著嘗試使遠端服務看起來像程式語言中的本地物件一樣毫無意義,因為這是一個根本不同的事情。 REST 的部分吸引力在於,它並不試圖隱藏它是一個網路協議的事實(儘管這似乎並沒有阻止人們在 REST 之上構建 RPC 庫)。
|
||||
|
||||
|
@ -275,7 +275,7 @@ SELECT COUNT(*)FROM emails WHERE recipient_id = 2 AND unread_flag = true
|
||||
|
||||
最常見的情況是,資料庫透過使用 **行鎖(row-level lock)** 來防止髒寫:當事務想要修改特定物件(行或文件)時,它必須首先獲得該物件的鎖。然後必須持有該鎖直到事務被提交或中止。一次只有一個事務可持有任何給定物件的鎖;如果另一個事務要寫入同一個物件,則必須等到第一個事務提交或中止後,才能獲取該鎖並繼續。這種鎖定是讀已提交模式(或更強的隔離級別)的資料庫自動完成的。
|
||||
|
||||
如何防止髒讀?一種選擇是使用相同的鎖,並要求任何想要讀取物件的事務來簡單地獲取該鎖,然後在讀取之後立即再次釋放該鎖。這能確保在讀取進行時,物件不會在髒的、有未提交的值的狀態(因為在那段時間鎖會被寫入該物件的事務持有)。
|
||||
如何防止髒讀?一種選擇是使用相同的鎖,並要求任何想要讀取物件的事務來簡單地獲取該鎖,然後在讀取之後立即再次釋放該鎖。這將確保在物件具有髒的、未提交的值時不會發生讀取(因為在此期間,鎖將由進行寫入的事務持有)。
|
||||
|
||||
但是要求讀鎖的辦法在實踐中效果並不好。因為一個長時間執行的寫入事務會迫使許多隻讀事務等到這個慢寫入事務完成。這會損失只讀事務的響應時間,並且不利於可操作性:因為等待鎖,應用某個部分的遲緩可能由於連鎖效應,導致其他部分出現問題。
|
||||
|
||||
@ -438,7 +438,7 @@ COMMIT;
|
||||
|
||||
#### 比較並設定(CAS)
|
||||
|
||||
在不提供事務的資料庫中,有時會發現一種原子操作:** 比較並設定(CAS, 即 Compare And Set,先前在 “[單物件寫入](#單物件寫入)” 中提到)。此操作的目的是為了避免丟失更新:只有當前值從上次讀取時一直未改變,才允許更新發生。如果當前值與先前讀取的值不匹配,則更新不起作用,且必須重試讀取 - 修改 - 寫入序列。
|
||||
在不提供事務的資料庫中,有時會發現一種原子操作:**比較並設定**(CAS, 即 Compare And Set,先前在 “[單物件寫入](#單物件寫入)” 中提到)。此操作的目的是為了避免丟失更新:只有當前值從上次讀取時一直未改變,才允許更新發生。如果當前值與先前讀取的值不匹配,則更新不起作用,且必須重試讀取 - 修改 - 寫入序列。
|
||||
|
||||
例如,為了防止兩個使用者同時更新同一個 wiki 頁面,可以嘗試類似這樣的方式,只有當用戶開始編輯頁面內容時,才會發生更新:
|
||||
|
||||
@ -806,7 +806,7 @@ WHERE room_id = 123 AND
|
||||
|
||||
在 [圖 7-11](../img/fig7-11.png) 中,事務 42 和 43 都在班次 1234 查詢值班醫生。如果在 `shift_id` 上有索引,則資料庫可以使用索引項 1234 來記錄事務 42 和 43 讀取這個資料的事實。 (如果沒有索引,這個資訊可以在表級別進行跟蹤)。這個資訊只需要保留一段時間:在一個事務完成(提交或中止),並且所有的併發事務完成之後,資料庫就可以忘記它讀取的資料了。
|
||||
|
||||
當事務寫入資料庫時,它必須在索引中查詢最近曾讀取受影響資料的其他事務。這個過程類似於在受影響的鍵範圍上獲取寫鎖,但鎖並不會阻塞事務指導其他讀事務完成,而是像警戒線一樣只是簡單通知其他事務:你們讀過的資料可能不是最新的啦。
|
||||
當事務寫入資料庫時,它必須在索引中查詢最近曾讀取受影響資料的其他事務。這個過程類似於在受影響的鍵範圍上獲取寫鎖,但鎖並不會阻塞事務直到其他讀事務完成,而是像警戒線一樣只是簡單通知其他事務:你們讀過的資料可能不是最新的啦。
|
||||
|
||||
在 [圖 7-11](../img/fig7-11.png) 中,事務 43 通知事務 42 其先前讀已過時,反之亦然。事務 42 首先提交併成功,儘管事務 43 的寫影響了 42 ,但因為事務 43 尚未提交,所以寫入尚未生效。然而當事務 43 想要提交時,來自事務 42 的衝突寫入已經被提交,所以事務 43 必須中止。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user