生產注意事項

wongchaofan發表於2024-05-20

要使用事務, 部署的所有成員的版本:

部署
最低限度featureCompatibilityVersion
副本集
4.0
分片叢集
4.2

預設情況下,事務的執行時間必須少於一分鐘。您可以使用 例項transactionLifetimeLimitSeconds來 修改此限制mongod。對於分片叢集,必須為所有分片副本整合員修改該引數。超過此限制的事務將被視為已過期,並將透過定期清理過程中止。

MongoDB 根據需要建立儘可能多的 oplog 條目來封裝事務中的所有寫操作,而不是為事務中的所有寫操作建立一個條目。這消除了單個 oplog 條目對其所有寫入操作施加的事務總大小 16MB 的限制。儘管取消了總大小限制,但每個 oplog 條目仍然必須在 BSON 文件大小限制 16MB 之內。

單個Oplog在16M限制內,可使用多個oplog封裝。

不能在具有writeConcernMajorityJournalDefault設定為false的碎片的分片叢集上執行事務。(例如具有使用記憶體儲存引擎的投票成員的分片)。

預設情況下,事務最多等待5幾毫秒來獲取事務中操作所需的鎖。如果事務無法在幾5毫秒內獲取所需的鎖,則事務將中止。

事務在中止或提交時釋放所有鎖。

您可以使用該maxTransactionLockRequestTimeoutMillis 引數來調整事務等待獲取鎖的時間。增加maxTransactionLockRequestTimeoutMillis允許事務中的操作等待指定的時間來獲取所需的鎖。這可以幫助避免瞬時併發鎖獲取時的事務中止,例如快速執行的後設資料操作。但是,這可能會延遲死鎖事務操作的中止。

maxTransactionLockRequestTimeoutMillis to -1 您還可以使用特定於操作的超時。

需要集合鎖的DDL操作

db.collection.createIndex()DDL 操作employees

需要資料庫鎖的DDL操作

在正在進行的collMod事務完成之前,collMod 操作必須等待獲取鎖。影響hr資料庫或其任何集合並在掛起期間啟動的任何新事務必須等到 collMod完成後。

事務內的讀取操作可能會返回舊資料,這稱為 陳舊讀取。事務內的讀取操作不能保證看到其他已提交事務執行的寫入或非事務寫入。例如,考慮以下序列:

  1. 事務正在進行中。

  2. 事務外的寫入會刪除文件。

  3. 事務內的讀取操作可以讀取現在已刪除的文件,因為該操作使用寫入操作之前的快照。

為了避免事務內的讀取返回舊資料,查詢更新可以使用db.collection.findOneAndUpdate()方法。

示例

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()

相關文章