由于超出容量限制 不能创建新事务_事务使用需考虑的因素

MongoDB 的事务在默认情况下有运行时间限制,不能超过一分钟。事务的 oplog 条目必须小于16MB,且需注意 WiredTiger 缓存压力。事务在遇到错误或无法获取锁时会中止,可以通过 maxTransactionLockRequestTimeoutMillis 参数调整锁请求超时。此外,DDL操作可能会影响其他事务和非事务操作的执行,可能导致写冲突和陈旧读取问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

21c3ca6e4b16531a633e40c1571309d7.png

参考官方文档:https://docs.mongodb.com/manual/core/transactions-production-consideration/运行时间限制
默认情况下,事务的运行时间必须小于一分钟。 您可以使用transactionLifetimeLimitSeconds修改此限制。 超过此限制的事务将被视为已过期,并将通过定期清理过程中止。oplog 大小限制
当事务提交时,如果事务包含任何写操作,则会创建单个oplog(操作日志)条目。 也就是说,事务中的各个操作没有相应的oplog条目。 而是,单个oplog条目包含事务中的所有写操作。 事务的oplog条目必须在16MB的BSON文档大小限制内。WiredTiger缓存
防止存储缓存压力对性能产生负面影响:

  • 放弃事务时,中止事务。
  • 在事务中的单个操作期间遇到错误时,中止事务并重试事务。


transactionLifetimeLimitSeconds还确保定期中止过期的事务以减轻存储缓存压力。
默认情况下,事务等待最多5毫秒来获取事务中的操作所需的锁。 如果事务无法在5毫秒内获取其所需的锁定,则事务将中止。事务和锁定
默认情况下,事务等待最多5毫秒来获取事务中的操作所需的锁。 如果事务无法在5毫秒内获取其所需的锁定,则事务将中止。
事务在中止或提交时释放所有锁。
TIP:
在开始事务之前立即创建或删除集合时,如果在事务中访问集合,则发出写入关注“多数”的创建或删除操作,以确保事务可以获取所需的锁。锁需求超时
您可以使用maxTransactionLockRequestTimeoutMillis参数来调整事务等待获取锁的时间。 增加maxTransactionLockRequestTimeoutMillis允许事务中的操作等待指定的时间来获取所需的锁。 这有助于避免在一瞬间并发锁定获取(例如快速运行的元数据操作)上的事务中止。 但是,这可能会延迟死锁事务操作的中止。
还可以通过将maxTransactionLockRequestTimeoutMillis设置为-1来使用特定于操作的超时。默认值是5等待DDL操作和事务
如果正在进行多文档事务,则影响相同数据库的新DDL操作会在事务后面等待。 虽然存在这些挂起的DDL操作,但是与挂起的DDL操作访问同一数据库的新事务无法获取所需的锁,并在等待maxTransactionLockRequestTimeoutMillis后将中止。 此外,访问同一数据库的新非事务操作将阻塞,直到达到其maxTimeMS限制。为了说明,比较以下两种情况:
考虑一种情况,即正在进行的事务对hr数据库中的employees集合执行各种CRUD操作。 当该事务正在进行时,单独事务可以启动并完成访问hr数据库中的foobar集合。
但是,请考虑这样一种情况:正在进行的事务对hr数据库中的employees集合执行各种CRUD操作,并且发出单独的DDL操作以在hr数据库中的fluffy集合上创建索引。 DDL操作等待事务完成。
当DDL操作处于挂起状态时,新事务会尝试访问hr数据库中的foobar集合。 如果DDL操作对于maxTransactionLockRequestTimeoutMillis保持挂起,则新事务将中止。正在进行的事务和写冲突
如果正在进行多文档事务并且事务外部的写入修改了事务中稍后将修改的文档,则事务因写入冲突而中止。
如果正在进行多文档事务并且已锁定以修改文档,则当事务外部的写入尝试修改同一文档时,写入将等待直到事务结束。正在进行的事务和陈旧读
事务内部的读取操作可以返回陈旧的数据。 也就是说,事务内的读操作不能保证看到由其他已提交事务或非事务性写操作执行的写操作。 例如,请考虑以下顺序:1)事务正在进行中2)事务外部的写入删除文档3)事务内部的读取操作能够读取现在删除的文档,因为操作正在使用写之前的快照。
要避免单个文档的事务内部陈旧读取,可以使用db.collection.findOneAndUpdate()方法。 例如:
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
employeesCollection = session.getDatabase("hr").employees;
employeeDoc = employeesCollection.findOneAndUpdate(
{ _id: 1, employee: 1, status: "Active" },
{ $set: { employee: 1 } },
{ returnNewDocument: true }
);

  • 如果employee 文档 在事务之外已更改,则事务将中止。
  • 如果employee 文档未更改,则事务将返回文档并锁定文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值