【问题标题】:TokuMX MVCC Transactions in JavaJava 中的 TokuMX MVCC 事务
【发布时间】:2014-07-11 13:35:46
【问题描述】:

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

似乎正在发生这种情况:

  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 的预期行为(或者我做错了什么)?

【问题讨论】:

    标签: java transactions mvcc tokumx


    【解决方案1】:

    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

    【讨论】:

    • 感谢您回复我。我已经明白你在说什么,也许我问的问题很糟糕。希望编辑将有助于澄清。再次感谢。
    • 对不起,我使用单个动作作为一个简单的例子。在工作代码中,多个文档被更新并且连接保持独立(每个实例一个 mongoClient)。我正在尝试比较这两种类型的事务以及它们在不同工作负载下的表现——因此在这种情况下,了解 tokumx 如何处理 MVCC 事务对我来说很重要。我已经为可序列化事务设置了测试,所以我对此很满意。感谢您的帮助。
    • 你应该知道,如果你的事务是单个更新,你可以直接运行它,你不需要将它包装在一个事务中。如果您想使用多语句事务,您可能需要“可序列化”隔离而不是 MVCC,如果您将读取作为事务的一部分:docs.tokutek.com/tokumx/…
    • 另外,你需要为事务保留一个连接,否则连接池会使你的事务行为不正常:docs.tokutek.com/tokumx/…
    • 您好,非常感谢您花在这方面的时间,但我认为您误解了我的意思。我正在比较可序列化事务与 tokumx 中的 mvcc 事务的比较。我有一个可序列化事务的工作模拟,但在 MVCC 中,一些更新可能会丢失。我已经确定当两个事务重叠时记录会丢失,但不会相互阻塞——如果由于某种原因其中一个事务在另一个之前完成,这是可能的。我写了一个解决方法,涉及获取 MVCC 快照,然后使用可序列化事务进行写入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2012-11-20
    • 1970-01-01
    • 2020-11-27
    • 2020-04-13
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多