0
votes

I am designing the layout of my datastore, but am wondering whether my approach is correct due to the nature of transactions.

I have an Account entity:

Account
=======
(int) balance (in cents)

and a Transfer entity:

Transfer
========
(Key) fromAccount
(Key) toAccount
(int) amount (in cents)

Now the transfer is pretty easy:
In a transaction I insert a Transfer entity with the appropriate values (fromAccount, toAccount, amount), and I update the two Account entities with the correct balance.

So far so good. But the documentation reads:

When two or more transactions simultaneously attempt to modify entities in one or more common entity groups, only the first transaction to commit its changes can succeed; all the others will fail on commit.

Doesn't this create a big problem? If I have many transfers happening at the same time, they might all want to update the same Account so they would all fail.

What is the recommended approach for this?

EDIT: In the documentation, they talk about retrying the same transaction, but if I have too many write operations on one account, this will just result in endless retries won't it?

1

1 Answers

2
votes

If multiple transactions are trying to update a given entity, only one of them will succeed. You have no option but to retry the failed transfer(s) either immediately or after some delay.

I'm not sure what your exact use case is, and why you would have several simultaneous transfers from/to a single account. But if that is what you need to address, one solution could be to process the transfers in batch. You could either queue the transfers and process the queue or use your Transfers Kind with a status (Pending/Completed) and process the entities one after the other.

Regarding retries and never ending retries - it depends on the number of new transfer requests coming in for a single account. If the new requests are coming at a higher rate than what you are able to process, it would be a problem. Otherwise, it should not be a problem as you would be committing one transaction at a time and eventually all will be done.

If you share more details (such as expected number of total transfers per hour/day, simultaneous transfers to/from a single account) perhaps the community could suggest other options.