Why is this transaction aborted?

While I was experimenting with transactions, I found a case that according to the documentation should not fail.

The documentation says:

If two transactions conflict - that is, they’ve written to the same row of a data table, or one transaction writes into a row another is reading from - one or both of them will be aborted.

The following two snippets read one row from the same table and update it. They don’t update the same row, so the transaction should not fail, but if I run them on two Python consoles at the same time, one of the two transactions fails.

Import and uplink connection:

import anvil.server, tables, time
anvil.server.connect("<connection string>")

Script on the first console:

with tables.Transaction():
  row = tables.app_tables.my_table.get(col_1='test 1')
  row['col_2'] = '1'
  time.sleep(2)
  row['col_2'] = '2'

Script on the second console:

with tables.Transaction():
  row = tables.app_tables.my_table.get(col_1='test 2')
  row['col_2'] = '1'
  time.sleep(2)
  row['col_2'] = '2'

This seems to be a bug. I can reproduce it consistently. Ticket raised. Thanks for a precise report!

Is this blocking you from getting something done? If so we can try to figure out a workaround for now. Of course, you can write a retry loop or use the auto-retry in @anvil.tables.in_transaction, but perhaps the delay that introduces is unacceptable for your use-case.

Thanks for checking it.

The little test has a 2 second pause between writes, which increases the chances of conflict (well, of reproducing the bug).

In our real world the transactions have only one or two writes at the very end, and considering our very low traffic, it is very unlikely that this will happen. And if it happens, the transaction will be retried and everything will keep working without problems.

1 Like

Good to know it’s not causing you any serious pain, thanks again for letting us know.