Duplicate entries in High Replication Datastore

可紊 提交于 2019-12-04 20:03:14

The Possible Solution appears to have the same problem as the original code. Imagine the race condition if two servers execute the same instructions practically simultaneously. With Google's overprovisioning, that is sure to happen once in a while.

A more robust solution should use Transactions and a rollback for when concurrency causes a consistency violation. The User entity should be the parent of its own Entity Group. Increment a records counter field in the User entity within a transaction. Create the new FeelTrackerRecord only if the Transaction completes successfully. Therefore the FeelTrackerRecord entities must have a User as parent.

Edit: In the case of your code the following lines would go before user = User.query(... :

Transaction txn = datastore.beginTransaction();
try {

and the following lines would go after user.put() :

    txn.commit();
} finally {
    if (txn.isActive()) {
        txn.rollback();
    }
}

That may overlook some flow control nesting detail, it is the concept that this answer is trying to describe.

With an active transaction, if multiple processes (for example on multiple servers executing the same POST concurrently because of overprovisioning) the first process will succeed with its put and commit, while the second process will throw the documented ConcurrentModificationException.

Edit 2: The transaction that increments the counter (and may throw an exception) must also create the new record. That way if the exception is thrown, the new record is not created.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!