【MongoDB】4.0版本事務上手測試

來源:互聯網
上載者:User

標籤:false   版本   必須   min   sse   command   val   connect   沒有   

事務上手測試基礎:

原來3版本的只能叫單文檔事務,即針對行的事務。所以沒必要顯式提供調用,多文檔事務由於有損耗,照顧到效能的需求,提供了事務開啟關閉的介面。
多行,多集合,多庫之間讀肯定會牽扯到一致性讀,所以多文檔事務肯定是有必要的。
4.2版本可能會支援分區系統多文檔事務,4.0的多文檔事務最多隻面向複製集

準備

集合:

use dba;[10.240.129.36:[email protected]]> db.coll_2.find()[10.240.129.36:[email protected]]> db.coll_1.find(){ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }

精簡命令:

// 顯式開啟一個會話(難道通過shell連結來本身不就是會話嗎?)session=db.getMongo().startSession()// 顯式開啟事務session.startTransaction()// 擷取表對象coll_1=session.getDatabase(‘dba‘).coll_1coll_2=session.getDatabase(‘dba‘).coll_2;// 使用表對象的插入函數進行插入coll_1.insertOne({‘not_test‘:false})coll_2.insertOne({‘not_test‘:false})// 提交事務session.commitTransaction()// 復原事務session.abortTransaction()// 檢查事務準確性db.coll_1.find()db.coll_2.find()
逾時參數怎麼設定?

預設事務生命週期為60秒,超出後會被自動清理

// The minimum value for transactionLifetimeLimitSeconds is 1 second.db.adminCommand( { setParameter: 1, transactionLifetimeLimitSeconds: 30 } )// You can also set parameter transactionLifetimeLimitSeconds at startup time.// 可以考慮寫在設定檔中mongod --setParameter "transactionLifetimeLimitSeconds=30"
第一次嘗試

因為忘記設定回溯相容性,執行失敗,在同一個shell中進行設定後,再次插入,提示事務不存在

[10.240.129.36:[email protected]]> Session.startTransactions()2018-06-30T14:17:10.670+0800 E QUERY    [js] ReferenceError: Session is not defined :@(shell):1:1[10.240.129.36:[email protected]]> db.getMongo()connection to 127.0.0.1:30001[10.240.129.36:[email protected]]> db.getMongo().startSession()session { "id" : UUID("887f4564-4f8a-4783-886d-a55a536f41aa") }[10.240.129.36:[email protected]]> session=db.getMongo().startSession()session { "id" : UUID("9b3e10b9-93cd-4010-b1a3-0e7b49796db3") }[10.240.129.36:[email protected]]> session.startTransaction()[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1;dba.coll_1[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;dba.coll_2[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})// 回溯相容性要求為4,也就是說想開啟事務必須是mongod4以上的版本2018-06-30T14:28:55.708+0800 E QUERY    [js] WriteCommandError: Transactions are only supported in featureCompatibilityVersion 4.0. See http://dochub.mongodb.org/core/4.0-feature-compatibility for more information. :WriteCommandError({    "ok" : 0,    "errmsg" : "Transactions are only supported in featureCompatibilityVersion 4.0. See http://dochub.mongodb.org/core/4.0-feature-compatibility for more information.",    "code" : 50773,    "codeName" : "Location50773"})[email protected]/mongo/shell/bulk_api.js:420:48Bulk/[email protected]/mongo/shell/bulk_api.js:902:1Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21[email protected]/mongo/shell/crud_api.js:252:9@(shell):1:1[10.240.129.36:[email protected]]> db.adminCommand({setFeatureCompatibilityVersion:‘4.0‘}){ "ok" : 1 }// 可以看到,報錯,重新設定版本相容性後,原先的事務出現了問題[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false})2018-06-30T14:31:16.706+0800 E QUERY    [js] WriteCommandError: Given transaction number 0 does not match any in-progress transactions. :WriteCommandError({    "errorLabels" : [        "TransientTransactionError"    ],    "ok" : 0,    "errmsg" : "Given transaction number 0 does not match any in-progress transactions.",    "code" : 251,    "codeName" : "NoSuchTransaction"})[email protected]/mongo/shell/bulk_api.js:420:48Bulk/[email protected]/mongo/shell/bulk_api.js:902:1Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21[email protected]/mongo/shell/crud_api.js:252:9@(shell):1:1// 事務怎麼也調不好了[10.240.129.36:[email protected]]> session.startTransaction()2018-06-30T14:33:53.293+0800 E QUERY    [js] Error: Transaction already in progress on this session. :[email protected]/mongo/shell/session.js:732:1[email protected]/mongo/shell/session.js:925:17@(shell):1:1[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]>[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> db.getMongo().abortTransaction[10.240.129.36:[email protected]]> exit// 直接退出當前串連
第二次嘗試:
[10.240.129.36:[email protected]]> session=db.getMongo().startSession()session { "id" : UUID("b82d71b0-b698-4909-b5b8-a7845dba98b2") }[10.240.129.36:[email protected]]>  session.startTransaction()[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1dba.coll_1[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;dba.coll_2[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b37270429c5c0c486b4b17b")}[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})// 這裡的交易回復可能是因為逾時引起的,預設事務生命週期最大值為1分鐘2018-06-30T15:00:50.629+0800 E QUERY    [js] WriteCommandError: Transaction 0 has been aborted. :WriteCommandError({    "errorLabels" : [        "TransientTransactionError"    ],    "ok" : 0,    "errmsg" : "Transaction 0 has been aborted.",    "code" : 251,    "codeName" : "NoSuchTransaction"})[email protected]/mongo/shell/bulk_api.js:420:48Bulk/[email protected]/mongo/shell/bulk_api.js:902:1Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21[email protected]/mongo/shell/crud_api.js:252:9@(shell):1:1[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false})2018-06-30T15:00:59.308+0800 E QUERY    [js] WriteCommandError: Transaction 0 has been aborted. :WriteCommandError({    "errorLabels" : [        "TransientTransactionError"    ],    "ok" : 0,    "errmsg" : "Transaction 0 has been aborted.",    "code" : 251,    "codeName" : "NoSuchTransaction"})[email protected]/mongo/shell/bulk_api.js:420:48Bulk/[email protected]/mongo/shell/bulk_api.js:902:1Bulk/[email protected]/mongo/shell/bulk_api.js:1150:21[email protected]/mongo/shell/crud_api.js:252:9@(shell):1:1// 事務逾時復原之後,應該還可以重開新的事務才對,這裡老是報錯[10.240.129.36:[email protected]]> session.startTransaction()2018-06-30T15:01:04.932+0800 E QUERY    [js] Error: Transaction already in progress on this session. :[email protected]/mongo/shell/session.js:732:1[email protected]/mongo/shell/session.js:925:17@(shell):1:1// 內部已經復原掉了,結果竟然需要我手動復原才行,暈[10.240.129.36:[email protected]]> session.abortTransaction()[10.240.129.36:[email protected]]> session.startTransaction()[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b372ac229c5c0c486b4b17e")}[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b372ac529c5c0c486b4b17f")}// 試試能不能進行explain操作[10.240.129.36:[email protected]]> coll_1.explain().find({‘test_explain‘:1})2018-06-30T15:03:09.375+0800 E QUERY    [js] Error: explain failed: {    "ok" : 0,    "errmsg" : "Cannot run ‘explain‘ in a multi-document transaction.",    "code" : 50767,    "codeName" : "Location50767"} :  // 果然是報錯了呢,在事務中不能進行explain操作[email protected]/mongo/shell/utils.js:25:13[email protected]/mongo/shell/explainable.js:31:1constructor/[email protected]/mongo/shell/explain_query.js:171:24constructor/[email protected]/mongo/shell/explain_query.js:210:26[email protected]/mongo/shell/utils.js:594:1@(shell2):1:1// 嘗試提交時報錯[10.240.129.36:[email protected]]> session.commitTransaction()2018-06-30T15:04:21.985+0800 E QUERY    [js] Error: command failed: {    "errorLabels" : [        "TransientTransactionError"    ],    "ok" : 0,    "errmsg" : "Transaction 1 has been aborted.",    "code" : 251,    "codeName" : "NoSuchTransaction"} :[email protected]/mongo/shell/utils.js:25:13[email protected]/mongo/shell/assert.js:18:14[email protected]/mongo/shell/assert.js:534:17[email protected]/mongo/shell/assert.js:618:16[email protected]/mongo/shell/session.js:929:17@(shell):1:1[10.240.129.36:[email protected]]> db.coll_1.find(){ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }[10.240.129.36:[email protected]]> db.coll_2.find()// 這邊可以看到,插入語句並沒有真正被執行[10.240.129.36:[email protected]]> session.commitTransaction()2018-06-30T15:05:46.288+0800 E QUERY    [js] Error: command failed: {    "errorLabels" : [        "TransientTransactionError"    ],    "ok" : 0,    "errmsg" : "Transaction 1 has been aborted.",    "code" : 251,    "codeName" : "NoSuchTransaction"} :[email protected]/mongo/shell/utils.js:25:13[email protected]/mongo/shell/assert.js:18:14_asser[email protected]/mongo/shell/assert.js:534:17[email protected]/mongo/shell/assert.js:618:16[email protected]/mongo/shell/session.js:929:17@(shell):1:1// 這兒又抽風了,內部復原之後禁止提交操作,嘗試進行復原,結果說已經提交了,不能復原,真是暈死[10.240.129.36:[email protected]]> session.abortTransaction()2018-06-30T15:06:04.162+0800 E QUERY    [js] Error: Cannot call abortTransaction after calling commitTransaction. :[email protected]/mongo/shell/session.js:764:1[email protected]/mongo/shell/session.js:934:17@(shell):1:1
第三次嘗試(成功提交):
[10.240.129.36:[email protected]]> session=db.getMongo().startSession()session { "id" : UUID("e7935985-160d-4969-adfe-3bae401e155f") }[10.240.129.36:[email protected]]> session.startTransaction()[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1dba.coll_1[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;dba.coll_2[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b373202d0b208b7386e9c20")}[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b373202d0b208b7386e9c21")}[10.240.129.36:[email protected]]> session.commitTransaction()[10.240.129.36:[email protected]]> use dbaswitched to db dba[10.240.129.36:[email protected]]> db.coll_1.find(){ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }[10.240.129.36:[email protected]]> db.coll_2.find(){ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }
第四次嘗試(測試復原):
[10.240.129.36:[email protected]]> session=db.getMongo().startSession()session { "id" : UUID("e7935985-160d-4969-adfe-3bae401e155f") }[10.240.129.36:[email protected]]> session.startTransaction()[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1dba.coll_1[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;dba.coll_2[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b373202d0b208b7386e9c20")}[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b373202d0b208b7386e9c21")}[10.240.129.36:[email protected]]> session.commitTransaction()[10.240.129.36:[email protected]]> use dbaswitched to db dba[10.240.129.36:[email protected]]> db.coll_1.find(){ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }[10.240.129.36:[email protected]]> db.coll_2.find(){ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }[10.240.129.36:[email protected]]> session=db.getMongo().startSession()session { "id" : UUID("cc0e2d23-1766-4ea5-87a5-957efcae28ad") }[10.240.129.36:[email protected]]> session.startTransaction()[10.240.129.36:[email protected]]> coll_1=session.getDatabase(‘dba‘).coll_1dba.coll_1[10.240.129.36:[email protected]]> coll_2=session.getDatabase(‘dba‘).coll_2;dba.coll_2[10.240.129.36:[email protected]]> coll_1.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b3732f0d0b208b7386e9c22")}[10.240.129.36:[email protected]]> coll_2.insertOne({‘not_test‘:false}){    "acknowledged" : true,    "insertedId" : ObjectId("5b3732f1d0b208b7386e9c23")}[10.240.129.36:[email protected]]> session.abortTransaction()[10.240.129.36:30001_primar[email protected]]> db.coll_2.find(){ "_id" : ObjectId("5b373202d0b208b7386e9c21"), "not_test" : false }[10.240.129.36:[email protected]]> db.coll_1.find(){ "_id" : ObjectId("5b371e120d6160b73a9fcee6"), "test" : true }{ "_id" : ObjectId("5b371e6d0d6160b73a9fcee7"), "test" : true }{ "_id" : ObjectId("5b373202d0b208b7386e9c20"), "not_test" : false }
注意

預設事務逾時時間有點短,1分鐘
預設鎖等待時間短,5毫秒
事務的操作有些繁瑣,不如RDS的 begin commit rollback方便(指SHELL操作)
一個事務的對應的oplog不能超過16M(指BSON格式的檔案大小)
明確交易功能的開啟對WT緩衝提出了新的要求。類似於IBP事務不按時提交,類似undo用於存放快照或者舊版本的東西肯定會佔用大量WT的空間。

【MongoDB】4.0版本事務上手測試

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.