serialização e consequências da transação libpqxx
-
21-12-2019 - |
Pergunta
Para minha implementação, uma determinada gravação deve ser feita em massa e sem chance de outra interferir.
Eu estive contado que duas transações concorrentes dessa forma farão com que a primeira bloqueie a segunda, e a segunda pode ou não ser concluída após a primeira.
Por favor poste a documentação que confirma isso.Além disso, o que exatamente acontece com a segunda transação se a primeira estiver bloqueada?Será enfileirado, falhará ou alguma combinação?
Se isso não puder ser confirmado, o nível de isolamento da transação para esta transação deve ser definido como SERIALIZABLE
?Se sim, como isso pode ser feito com instruções preparadas pela libpqxx?
Se as transações forem serializadas, a segunda transação falhará ou ficará na fila até que a primeira seja concluída?
Se algum deles falhar, como isso pode ser detectado com libpqxx?
Solução
A única maneira de evitar conclusivamente os efeitos de simultaneidade é LOCK TABLE ... IN ACCESS EXCLUSIVE MODE
cada tabela que você deseja modificar.
Isso significa que você está fazendo apenas uma coisa de cada vez.Isso também leva a problemas divertidos com impasses se você nem sempre adquirir seus bloqueios na mesma ordem.
Então, normalmente, o que você precisa fazer é descobrir quais são exatamente as operações que você deseja realizar e como elas interagem.Determine quais efeitos simultâneos você pode tolerar e como evitar aqueles que não pode.
Esta questão, tal como está, é demasiado ampla para ser respondida de forma útil.
As opções incluem:
Bloqueio exclusivo de tabelas.(Isto é o único caminho para fazer um upsert de várias linhas sem problemas de simultaneidade no PostgreSQL agora).Cuidado com os impasses relacionados à atualização de bloqueio e à ordem de bloqueio.
uso apropriado de
SERIALIZABLE
isolamento - mas lembre-se, você deve ser capaz de manter um registro do que fez durante uma transação e tentar novamente se a transação for abortada.Bloqueio cuidadoso em nível de linha -
SELECT ... FOR UPDATE
,SELECT ... FOR SHARE
."Bloqueio otimista"/controle de simultaneidade otimista, quando apropriado
Escrever suas consultas de maneira que as tornem mais amigáveis para operações simultâneas.Por exemplo, substituindo ciclos de leitura-modificação-gravação por atualizações locais.