\set outros NULL
\set de_id random_zipfian(0, 1000, 1.5)
\set para_id random_zipfian(0, 1000, 1.5)
\set valor random_zipfian(1, 100, 1.5)

begin;
	-- validação de saldo
	select balance as saldo
		from l0.account
		where aid = :de_id \gset

-- aplicação retorna rápido quando a conta de origem não tem saldo
\if (:saldo >= :valor or :de_id = 0) and (:de_id <> :para_id)

	-- transação iniciando com locks de longa duração
	-- insert on conflict do update + deadlock
	insert into l0.account (aid, balance)
		values
			(:de_id, -:valor)
		on conflict (aid) do
		update set balance = account.balance + excluded.balance;
	insert into l0.account (aid, balance)
		values
			(:para_id, :valor)
		on conflict (aid) do
		update set balance = account.balance + excluded.balance;

	-- transação financeira
	insert into l0.transaction ("...")
		values
			(:outros)
		returning tid \gset

	-- entradas na transação
	insert into l0.entry (aid, tid, value)
		values
			(:de_id, :tid, -:valor),
			(:para_id, :tid, :valor);
\endif
end;
