2

我对 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
}

但是,如果源或目标已经在事务表中(作为源或目标),我真正想要的是被锁定。

所以我的问题是是否有可能以允许上述方式的方式设置索引,或者如果没有其他方式来实现这一点。

谢谢!

4

2 回答 2

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 }
于 2012-08-09T18:19:53.453 回答
0

要实际放置一个确实回答了您将在评论中看到的问题的答案,我建议在子文档上放置一个唯一索引,以便文档看起来像:

{
    _id:{},
    accounts: [1,2],
    source: 1,
    destination: 2
}

在帐户字段上放置唯一索引将在帐户 1 和帐户 2 上生成任何未决交易的锁定,以便停止进一步的交易,直到完成。因此,这意味着如果存在待处理的事务,那么无论源还是目标是 1 还是 2,它都会退出。

但是,在某些情况下,您无法保证子文档的顺序,因此对于像这样的整体交易,我不会使用子文档来判断交易的方向,例如:

dest_source: [1,2]

为了表示帐户 1 正在支付帐户 2,因为此索引的顺序可能会随着您保存的方式而改变,因此我将仅使用子文档来创建一个索引类型,该索引类型在使用sourceanddestination字段实际时考虑索引内的排列了解交易的方向,因为即使文档更改顺序,您仍然可以通过命名字段了解方向。

我相信这是 OP 真正想要的。

于 2012-08-10T07:27:53.033 回答