Reputation: 16949
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
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
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