0

在同一文档上运行并发事务时如何保存高度竞争的记录?

似乎正在发生这种情况:

  1. MVCC 事务 A 开始。
  2. MVCC 事务 B 开始。
  3. 事务 A 更新 docA 和 docB。
  4. 事务 A 提交。
  5. 事务 B 更新 docA 和 docC - 当事务 A 已提交且不持有任何锁时,将获得锁。
  6. 事务 B 提交覆盖了转换 A 在 docA 上所做的工作。

这是示例代码:

        mongoClient = new MongoClient( "localhost" , 27017 );
        db = mongoClient.getDB("test");
        collection = db.getCollection("testData");

        //Create usable Mongo key from key String (i.e {_id:ObjectId("53b4477d44aef43e83c18922")})
        String key = "53b4477d44aef43e83c18922";
        String key2 = "53bfff9e44aedb6d98a5c578";
        ObjectId keyObj = new ObjectId(key);
        ObjectId keyObj2 = new ObjectId(key2);

        //Set up the transaction
        BasicDBObject transaction = new BasicDBObject();
        transaction.append("beginTransaction", 1);
        transaction.append("isolation", "mvcc");
        db.command(transaction);

        //Create search query
        BasicDBObject query = new BasicDBObject().append("_id",keyObj);
        BasicDBObject query2 = new BasicDBObject().append("_id",keyObj2);

        //Create set  
        BasicDBObject set = new BasicDBObject();
        set.append("$inc", new BasicDBObject().append("balance",50));

        //Run command
        collection.update(query, set);
        collection.update(query2, set);

        //Commit the transactions
        BasicDBObject commitTransaction = new BasicDBObject();
        commitTransaction.append("commitTransaction", 1);
        db.command(commitTransaction);

我可以做一个检查来决定是否提交交易吗?或者这是 TokuMX 的预期行为(或者我做错了什么)?

4

1 回答 1

2

TokuMX 多语句事务与 MySQL 多语句事务非常相似。在您的示例中,将在更新发生时持有文档级锁,因此对该记录的更新将被序列化。

如果因为两个事务同时更新同一个文档而发生冲突,update 方法将返回一个错误,说明存在锁冲突。

为了帮助您了解发生了什么,让两个线程运行它,但都没有提交。您将看到一个线程等待并最终因锁定超时错误而超时。

此外,如果您的事务是单个更新,您可以只运行它,您不需要将其包装在事务中。如果您想使用多语句事务,您可能需要“可序列化”隔离而不是 MVCC,如果您将读取作为事务的一部分:http: //docs.tokutek.com/tokumx/tokumx-transactions .html#tokumx-transactions-isolation-serializable此外,您需要为交易保留连接,否则连接池会使您的交易行为不正常: http: //docs.tokutek.com/tokumx/tokumx-transactions。 html#tokumx-transactions-multi-statement-drivers

于 2014-07-11T15:15:41.483 回答