您好,登錄后才能下訂單哦!
本篇內容介紹了“MySQL和MongoDB中多文檔事務支持扥功能的對比”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
MongoDB 4.0已經發布GA版本,并且有許多新功能和改進。在本文中,我們將重點關注主要功能,毫無疑問,這是對多文檔ACID事務的支持。我們將圍繞隔離級別、可重復讀、幻讀、事務沖突檢測等主要功能,通過實驗與MySQL一一做對比。
首先會簡述介紹下ACID事務隔離級別,然后再步入測試主題正文。
原子性(Atomicity):事務包含的所有操作要么全部成功,要么全部失敗,不存在成功一半的概念。典型例子“西方二元對立思想——非此即彼”:在二元邏輯體系中只存在兩種邏輯值,就是對和錯,或正和負,不存在既對又錯或非正非負的其他狀態。
一致性(Consistency):一個事務執行之前和執行之后都必須處于一致性狀態。典型例子:“金龍,你借我5000元,下個月開支給你。”不論金龍用什么方式給我轉賬,分幾次轉,借錢結束后我銀行卡里的余額增加5000元,金龍卡里少了5000元,不能突然蹦出來1萬來。
隔離性(Isolation):數據庫采用鎖機制來實現事務的隔離性,當多個事務同時更新數據庫中相同的數據時,只允許持有鎖的事務能更新該數據,其他事務必須等待,直到前一個事務釋放了鎖,其他事務才有機會更新該數據。典型例子:“你去醫院看病,要先到護士那里分診排號,如果多個患者加塞兒同時進來,大夫就發飆了,出去排隊,只能一個一個看”。
持久性(Durability):事務成功提交后,它對數據庫所做的修改就***保存下來,即使數據庫崩潰,數據還能恢復到事務成功提交后的狀態。典型例子:“你去ATM機取錢,結果ATM機故障了,你取出來了錢,卡里的余額不能沒減。”
一、局限性與限制條件
1、多文檔事務僅適用于副本集。
注:如果是單機,需切到副本集模式。
2、僅適用于WiredTiger存儲引擎。
3、如果你的架構是分片Sharding模式,事務是不支持的。分布式事務計劃在4.2版本里支持。
4、事務只支持CRUD操作,DDL、DCL操作不支持。
注:CRUD就是MySQL的DML,意思一樣叫法不同而已。
5、事務無法在config、admin和local系統數據庫中讀取或寫入。
6、事務無法在system.*(系統集合)里寫入。
7、不能有大事務寫入,寫入集不能超過16MB(類似MariaDB Galera Cluster寫入集wsrep_max_ws_size限制),否則客戶端直接報錯。
注:如果有大事務,應該考慮將這些大事務拆分成若干塊較小的事務。例如將大于2018年的狀態值更改為1,應考慮循環1萬條一批量更新,這一點跟MySQL玩法一樣。
二、我們***個事務
在開始事務之前,必須創建會話。事務不能在會話外運行。
var session1 = db.getMongo().startSession() var session2 = db.getMongo().startSession()
Mongo Shell里引入了三個用于創建,提交和終止事務的新命令:
session.startTransaction()
在當前會話中啟動事務
session.commitTransaction()
持久保存事務中的操作變更
session.abortTransaction()
終止事務操作所做的變更
1、在test庫創建t1表,并且插入4條數據。
演示一
演示二
空閑事務受transactionLifetimeLimitSeconds參數影響,默認60秒。
可通過以下命令查看:
db.adminCommand( { getParameter: 1, transactionLifetimeLimitSeconds: 1 } )
如果你想在線變更,可以通過下面的命令設置:
db.adminCommand( { setParameter: 1, transactionLifetimeLimitSeconds: 30 } )
也可以寫死在/etc/mongod.cnf配置文件里***生效,格式如下:
setParameter = transactionLifetimeLimitSeconds=30
注:空閑事務是指當一個事務長時間未提交,那么這個連接就不能關閉,內存就不釋放,并發一大,導致DB連接數增多,就會對性能產生影響。默認是60秒,你可以根據自己的情況設定閾值。超過這個閾值,服務端自動殺死未提交的空閑事務。
三、事務隔離性演示
演示一:事務沖突檢測
當兩個(或多個)并發事務修改相同的文檔時,會發生沖突。即使在尚未提交事務時,MongoDB也可以立即檢測到沖突。
這里和MySQL有些區別,MySQL可以通過參數innodb_lock_wait_timeout設置檢測到事務沖突后,自動終止回滾的時間,而MongoDB沒有提供該參數。
當在執行創建索引時,未加{background:1})后臺創建。
此時新事務將無法獲取所需的鎖,并且在等待參數maxTransactionLockRequestTimeoutMillis后事務終止回滾,默認值是5毫秒。
如果你想在線調整事務等待獲取鎖的時間,可以通過下面的命令設置:
db.adminCommand( { setParameter: 1, maxTransactionLockRequestTimeoutMillis: 15 } )
也可以寫死在/etc/mongod.cnf配置文件里***生效,格式如下:
setParameter = maxTransactionLockRequestTimeoutMillis=15
演示二:可重復讀
Repeatable Read (可重復讀)可避免臟讀、不可重復讀的發生。
不可重復讀側重點在于更新修改的數據,即在同一個事務里,兩次查詢的數據結果不一致。與臟讀的區別是:臟讀是一個事務讀取了另一個事務未提交的臟數據。
演示三:幻讀
在MySQL默認隔離級Repeatable Read下,剛才的操作,在會話二未提交的事務里,會莫名其妙地看到第5條數據,這種現象稱為幻讀。
幻讀和不可重復讀很像,但幻讀側重點在于新增和刪除,而不可重復讀側重點在于更改,共同之處都是一個事務中兩次查詢得到的數據結果不一致。
由此,從測試結果得出的結論是:
MongoDB采用的默認隔離級別是Snapshot一致性快照(特別是設置了readConcern=majority情況下,要讀某行數據的歷史版本時,依賴該隔離級別。)
Snapshot介于Repeatable Read與Serializable之間,既避免了臟讀、不可重復讀、幻讀,又不會因Serializable串行化降低并發性能。
“MySQL和MongoDB中多文檔事務支持扥功能的對比”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。