breeswish
2016-02-15 13:44:46 +08:00
就这个例子而言,可以在 pending 后进行检查,如果检查失败则回滚( MongoDB 文档 Rollback Operations 下的 Transactions in Pending State )。
你担心检查完和修改记录之间有其他操作,这个和两阶段递交没关系,你想做的是确保一次只有一个事务占用资源。可以实现一个锁。对于这个问题而言,可以在查询中增加条件解决(显然能解决的问题不如锁那么多):
db.accounts.update(
{ _id: t.destination, pendingTransactions: { $ne: t._id }, balance: { $lt: 100 - t.value} },
{ $inc: { balance: t.value }, $push: { pendingTransactions: t._id } }
)
注意增加了一个 balance: { $lt: 100 - t.value} 条件。 update 失败( 0 affected )直接 rollback 即可