Você pode corrigir esse problema com o seguinte índice:
CREATE INDEX accounts_user_idx ON accounts(user_id);
Como há tão poucos dados em sua tabela de exemplo, você terá que dizer ao PostgreSQL para usar uma varredura de índice:
SET enable_seqscan=off;
Agora seu exemplo vai funcionar!
Se isso parece magia negra, dê uma olhada nos planos de execução de consulta do seu
SELECT
e UPDATE
declarações. Sem o índice, ambos usarão uma varredura sequencial na tabela, lendo assim todas as linhas da tabela . Portanto, ambas as transações terminarão com um
SIReadLock
em toda a mesa. Isso aciona a falha de serialização.