

Transaction one attempts to acquire a row-level lock on the specified row, but it cannot: transaction two already holds such a lock. While reading the PostgreSQL Explicit Locking documentation, I was able to figure out that when deadlocks occurred, it wasn’t killing both transactions, but one, allowing the other to advance:
#POSTGRES DEADLOCK CODE#
Don’t be afraid of commenting your code when it is necessary to explain the non-obvious or to prevent bug regressions. Importantly, because (1) this bug was difficult to figure out and (2) the code to do the sorting isn’t obviously necessary, I made sure to leave a comment in each place it is used.

safe_insert_all ( Address, ordered_changes_list, conflict_target : :hash, on_conflict : :replace_all, timeout : Keyword. ** (stop) exited in: GenServer.call(, = Repo. Then while working on the indexer for POA Explorer, we started to get DBConnection.ConnectionError during our batch inserts. There was no need for user supplied locks and the server internally didn’t use locks either. When it was time to COMMIT the transaction, the server checked if that starting number matched the row’s current, outside-of-transactions number and if it did for all modified rows, then the transaction succeeded, if not, then it rolled back. My mental model of Postgres’s transactions was that it used MVCC ( Multiversion Concurrency Control): it kept around multiple copies of rows and transactions automatically kept track of which version they used on their first read or write.
