我对MongoDB相对较新,并且正在实施受此技术启发的交易:
http://cookbook.mongodb.org/patterns/perform-two-phase-commits/
我正在考虑如何阻止给定源/目标帐户的同时交易。例如,我可以通过声明源唯一索引来阻止同一源上的同时事务:
transactionsCollection.ensureIndex({"source":1}, {unique: true});
var newDoc = {source: sourceID, destination: destinationID,
amount: 100, state:"pending"}
transactionsCollection.save(newDoc, {safe:true}, function(error, t) {
if (error.name == "MongoError" && error.code == 11001)
// duplicate index, so I'm locked out
}
但是,如果源或目标已经在事务表中(作为源或目标),我真正想要的是被锁定。
所以我的问题是,是否可以以允许上述方式设置索引,或者如果没有其他方式来实现这一点。
谢谢!
答案 0 :(得分:2)
在记录中使用数组(下面为tags
)的唯一索引应该可以完成这个技巧。例如:
db.test.save({ name: 'one', tags: [1, 2] });
db.test.save({ name: 'two', tags: [3, 4] });
db.test.ensureIndex({ tags: 1 }, {unique: 1});
db.test.save({ name: 'three', tags: [4, 5] });
E11000 duplicate key error index: test.test.$tags_1 dup key: { : 4 }
答案 1 :(得分:0)
要实际放置一个实际回答问题的答案,您将在评论中看到我建议在子文档上放置一个唯一索引,以便文档看起来像:
{
_id:{},
accounts: [1,2],
source: 1,
destination: 2
}
在帐户字段上放置一个唯一索引会对任何挂起的交易产生一个帐户1和2的锁定,以便在完成之前停止进一步的交易。所以这意味着如果存在待处理的交易,那么它将拯救源或目的地是1还是2。
但是,在某些情况下你无法承担子文档的顺序,因为对于像这样的完整事务,我不会使用子文档来判断事务的方向,如:
dest_source: [1,2]
表示帐户1正在支付帐户2,因为此索引的顺序可能会随着您保存的方式而改变,因此我将仅使用子文档创建索引类型,该索引类型在使用{时考虑索引中的排列{1}}和source
字段实际了解交易的移动方向,因为即使文档更改顺序,您仍然可以通过命名字段了解方向。
我相信这就是OP真正想要的。