資料庫併發寫入問題-丟失更新與寫入偏差
MVCC
https://blog.csdn.net/qq_41775852/article/details/104853909
資料庫中的MVCC多版本併發控制(快照隔離)可以避免事務併發時的髒讀、不可重複讀以及幻讀的問題,但是卻無法避免丟失更新以及寫入偏差的問題。
丟失更新和寫入偏差
-
丟失更新:兩個事務併發讀取同一記錄,並在此基礎上修改記錄,並將其寫回資料庫,第二次寫入的結果會覆蓋第一次寫入的結果,導致資料庫狀態不一致。(丟失更新不僅出現在資料庫中,在應用程式多執行緒併發修改變數、分散式系統多主複製和無主複製中都會遇見)
例如:以下兩個事務,對A變數進行讀取10,T1事務將其減5,T2事務將其減8,兩事務提交之後,A的狀態為2,即T1事務的更新丟失了。如果A代表賬戶餘額,這種錯誤是不可接受的。
-
寫入偏差:寫入偏差可視為丟失更新問題的一般化,如果兩個事務讀取相同的記錄集,然後更新記錄集,不同的事務可能更新(插入、刪除)不同的記錄,則可能發生寫入偏差,導致資料庫狀態不一致或者不符合約束條件。
比如:1.醫院規定必須至少有一名醫生在值班。而兩個值班醫生同時進行請假事務,由於快照隔離,兩個醫生在檢查當前值班醫生數量時結果都為2,所以他們都可能請假。但是兩個事務提交之後,卻沒有醫生值班了,違反了醫院的規定。2.兩個使用者同時修改唯一使用者名稱,由於快照隔離,兩人都發現資料庫中無重複使用者名稱,則修改成功。兩個修改事務提交後,卻出現使用者名稱衝突。
如果併發事務沒有先讀取記錄集的值,而是直接寫入新的記錄集值,個人認為不屬於丟失更新或者寫入偏差,因為這導致的資料庫不一致,是使用者的錯誤邏輯所導致的,不是事務併發的原因。
丟失更新和寫入偏差的原因是相同的:併發事務首先查詢得到了相同的記錄集,然後根據此記錄集進行更新、插入、刪除等動作。由於快照隔離,事務感受不到其他事務對記錄集的更改,所以可以成功提交事務。但是併發事務的修改卻出現了矛盾,導致資料庫不一致。
解決方法
CAS
比較並設定(CAS, Compare And Set)是一種原子操作,此操作的目的是為了避免丟失更新:只有當前值從上次讀取時一直未改變,才允許更新發生。如果當前值與先前讀取的值不匹配,則更新不起作用,且必須重試讀取-修改-寫入序列。但是在提供快照隔離的事務中不起作用。
顯示鎖定
由於併發事務的更改都是基於讀取到的記錄集,所以只要事務對讀取到的記錄集加排他鎖,然後再對記錄集更新,提交事務之後才釋放排他鎖。這樣併發事務就只能讀取到其他事務以及提交後的資料,則不會出現不一致的狀態。
比如對於醫生請假事務,讀取並鎖定所有醫生的值班狀態,修改自己的值班狀態為請假,提交事務後釋放鎖。則第二個醫生在請假事務中讀取所有醫生值班狀態會阻塞,直到上一個事務提交,發現只剩自己一個人值班,則無法請假。
序列化隔離級別
使用事務的序列化隔離級別可以避免丟失更新和寫入偏差。
相關文章
- MongoDB 預設寫入關注儲存資料丟失問題與原始碼簡單分析MongoDB原始碼
- 【java】ObjectOutputStream & ObjectInputStream 多次寫入發生重複寫入相同資料的問題JavaObject
- Elasticsearch 如何保證寫入過程中不丟失資料的Elasticsearch
- Django資料庫連線丟失問題Django資料庫
- 實時資料併發寫入 Redis 優化Redis優化
- 如何將 EXCEL 資料寫入資料庫Excel資料庫
- openGauss 管理併發寫入操作
- 後臺登入提示:”登入失敗:資料庫目錄寫入許可權不足!“資料庫
- 併發場景下資料寫入功能的實現
- PbootCMS後臺登入提示:”登入失敗:資料庫目錄寫入許可權不足!“boot資料庫
- PbootCMS後臺登入提示:“登入失敗:資料庫目錄寫入許可權不足!”boot資料庫
- JAVA 資料寫入excel併傳送郵件JavaExcel
- 高併發下丟失更新的解決方案
- spark寫入hive資料SparkHive
- MongoDB寫入資料策略MongoDB
- 使用scrapy框架把資料非同步寫入資料庫框架非同步資料庫
- 資料庫高可靠,輕鬆解決事務丟失問題資料庫
- postman啟動載入很慢,更新替換版本後,資料丟失如何找回?Postman
- 求助 | 天氣預報資料採集,更新入庫的問題!
- Mysql增量寫入Hdfs(一) --將Mysql資料寫入Kafka TopicMySqlKafka
- 【問題追查】mc叢集寫入恍惚問題排查
- laravel5.1中cookie寫入問題LaravelCookie
- Web-請求資料+號丟失問題Web
- Elasticsearch 資料寫入原理分析Elasticsearch
- python——將excel檔案寫入mysql資料庫中PythonExcelMySql資料庫
- 登入失敗,提示“資料庫目錄許可權寫入不足”,可以操作設定資料庫目錄許可權為 777。資料庫
- Golang初學:高併發時寫入資料到不同的mapGolang
- 寫給關聯式資料庫開發者的 TDengine 入門指南資料庫
- 做資料庫分離讀寫時,sqlServer資料庫資料同步的問題:資料庫SQLServer
- 高併發下使用Redis悲觀鎖解決資料二次寫入Redis
- 10.註冊和登入功能實現(3)—— 註冊資料寫入資料庫資料庫
- java資料list寫入檔案Java
- 程式無任何報錯但是無法寫入資料庫資料庫
- ORA-1122/ORA-1208 資料檔案頭寫丟失故障
- 使用redis中setnx防止併發二次寫入Redis
- MapReduce之----往hbase資料庫寫入資料時, 出現資料異常資料庫
- 解決資料庫高併發訪問瓶頸問題資料庫
- python3-csv寫入中文亂碼問題Python