doorman
doorman

Reputation: 16949

Sharded counters within transaction

Taken from this artice on Sharding Counters, the following function demonstrates how a random shard is selected before it is incremented. This happens within a transaction.

def increment():
    """Increment the value for a given sharded counter."""
    def txn():
        index = random.randint(0, NUM_SHARDS - 1)
        shard_name = "shard" + str(index)
        counter = SimpleCounterShard.get_by_key_name(shard_name)
        if counter is None:
            counter = SimpleCounterShard(key_name=shard_name)
        counter.count += 1
        counter.put()
    db.run_in_transaction(txn)

Can only one transaction take place at a time and would that not prevent the different(random) sharded counters to be updated simultaneously? If so, what is the purpose of the sharding counters if only one sharded counter can be updated at a time?

Thanks!

Upvotes: 1

Views: 1170

Answers (2)

Peter Knego
Peter Knego

Reputation: 80340

No, this are separate transactions which do not block each other and also write limitation only applies to each entity separately.

Rationale: in your case SimpleCounterShard entities do not have a parent, meaning each entity is the root of it's own entity group. The transactions' scope is entity group and also concurrent write limit applies to entity group.

Upvotes: 3

dragonx
dragonx

Reputation: 15143

Transactions lock all the entities involved with the transaction. You can have multiple transactions going on as long as they're not touching the same entities.

Each shard is a separate entity. This allows you to update the various shards at the same time.

If the transaction happens to attempt to hit a shard (due to the random number generator) that is already in a transaction, then the transaction would fail.

Upvotes: 5

Related Questions