可用性
要使用事務, 部署的所有成員的版本:
部署
|
最低限度
featureCompatibilityVersion |
---|---|
副本集
|
4.0 |
分片叢集
|
4.2 |
執行時間限制
預設情況下,事務的執行時間必須少於一分鐘。您可以使用 例項transactionLifetimeLimitSeconds
來 修改此限制mongod
。對於分片叢集,必須為所有分片副本整合員修改該引數。超過此限制的事務將被視為已過期,並將透過定期清理過程中止。
Oplog 大小限制
MongoDB 根據需要建立儘可能多的 oplog 條目來封裝事務中的所有寫操作,而不是為事務中的所有寫操作建立一個條目。這消除了單個 oplog 條目對其所有寫入操作施加的事務總大小 16MB 的限制。儘管取消了總大小限制,但每個 oplog 條目仍然必須在 BSON 文件大小限制 16MB 之內。
單個Oplog在16M限制內,可使用多個oplog封裝。
Shard Configuration Restriction
不能在具有writeConcernMajorityJournalDefault設定為false的碎片的分片叢集上執行事務。(例如具有使用記憶體儲存引擎的投票成員的分片)。
獲取鎖
預設情況下,事務最多等待5
幾毫秒來獲取事務中操作所需的鎖。如果事務無法在幾5
毫秒內獲取所需的鎖,則事務將中止。
事務在中止或提交時釋放所有鎖。
鎖定請求超時
您可以使用該maxTransactionLockRequestTimeoutMillis
引數來調整事務等待獲取鎖的時間。增加maxTransactionLockRequestTimeoutMillis
允許事務中的操作等待指定的時間來獲取所需的鎖。這可以幫助避免瞬時併發鎖獲取時的事務中止,例如快速執行的後設資料操作。但是,這可能會延遲死鎖事務操作的中止。
maxTransactionLockRequestTimeoutMillis
to -1 您還可以使用特定於操作的超時。
需要集合鎖的DDL操作
db.collection.createIndex()
DDL 操作employees
需要資料庫鎖的DDL操作
在正在進行的collMod事務完成之前,collMod
操作必須等待獲取鎖。影響hr
資料庫或其任何集合並在掛起期間啟動的任何新事務必須等到 collMod
完成後。
進行中的事務和過時的讀取
事務內的讀取操作可能會返回舊資料,這稱為 陳舊讀取。事務內的讀取操作不能保證看到其他已提交事務執行的寫入或非事務寫入。例如,考慮以下序列:
-
事務正在進行中。
-
事務外的寫入會刪除文件。
-
事務內的讀取操作可以讀取現在已刪除的文件,因為該操作使用寫入操作之前的快照。
為了避免事務內的讀取返回舊資料,查詢更新可以使用db.collection.findOneAndUpdate()方法。
示例
-
將文件插入
employees
集合中
db.getSiblingDB("hr").employees.insertOne( { _id: 1, status: "Active" } )
-
開始會話
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } )
-
開始事務
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } ) employeesCollection = session.getDatabase("hr").employees
-
在事務內部使用
db.collection.findOneAndUpdate()
employeeDoc = employeesCollection.findOneAndUpdate( { _id: 1, status: "Active" }, { $set: { lockId: ObjectId() } }, { returnNewDocument: true } )
-
提交事務
session.commitTransaction()