Mongoose withTransaction 仅部分执行
Posted
技术标签:
【中文标题】Mongoose withTransaction 仅部分执行【英文标题】:Mongoose withTransaction only partially executes 【发布时间】:2020-12-27 11:00:22 【问题描述】:Mongoose 的 session.withTransaction
助手只执行第一次写入。代码如下:
const session = await mongoose.startSession();
await session.withTransaction(async () =>
const member = await Member.create([
name: 'John Doe'
email: 'johndoe@example.com',
], session );
await User.updateOne( _id: req.user.id , member: member._id , session );
);
此代码在数据库中创建一个新成员,但不更新用户。事务的意义不是只有在每个操作都成功的情况下才会进行吗?我究竟做错了什么;还是 Mongoose 无法做到这一点?
猫鼬:5.9.26, Node.js:14.9.0
【问题讨论】:
req.user.id
可能是字符串,users集合中_id
字段是什么类型?
@Joe 也是一个字符串,我已经检查过了,这不是问题。
尝试给 updateOne 调用一个回调来记录更新的文档,这样你就可以看到它匹配的内容。
@Joe hmmm...我遇到了一个错误,MongoError: Transaction 1 has been committed.
在 withTransaction 代码中发现了这条注释:“* 重要提示:此方法要求用户返回一个 Promise,所有不返回 Promise 的 lambdas 都会导致未定义的行为。”
【参考方案1】:
检查是否使用您将基于事务的模型启动会话有帮助:
const session = await Member.startSession();
【讨论】:
【参考方案2】:错误来自https://github.com/mongodb/mongo/blob/11c68393df88a6f1ea4855e6ac15e54ca9f9d976/src/mongo/db/transaction_participant.cpp#L1712
// Cannot change committed transaction but allow retrying commitTransaction command.
uassert(ErrorCodes::TransactionCommitted,
str::stream() << "Transaction " << requestTxnNumber << " has been committed.",
cmdName == "commitTransaction" || !o().txnState.isCommitted());
显然您正在尝试两次提交事务。确保您不重复使用它。始终结束会话:
const session = await mongoose.startSession();
try
await session.withTransaction(async () => ...)
finally
await session.endSession()
【讨论】:
【参考方案3】:你有没有试过这样写
session :session
【讨论】:
猜猜,这不会有什么不同。 session
应该是对象文字速记语法。
在猫鼬中有所不同我都试过了, session 不起作用。【参考方案4】:
确保您已设置副本,事务需要副本才能工作。
【讨论】:
以上是关于Mongoose withTransaction 仅部分执行的主要内容,如果未能解决你的问题,请参考以下文章
使用 JPA.withTransaction 的测试 Actor(java.lang.IllegalStateException:EntityManager 在测试时关闭)
Grails,使用 withTransaction 插入大量数据会导致 OutOfMemoryError
Django 嵌套事务 - “with transaction.atomic()”
升级 Play 到 2.4,Slick 到 3.1.1,值 withTransaction 不是 play.api.db.slick.Database 的成员