Eu realmente não entendo promessas sobre esperas em caso de acesso simultâneo a dados.
Todos os manuais operam por termo lock . Ninguém explica que o bloqueio provavelmente faz com que os clientes SQL aguardem a aquisição do bloqueio no lado do servidor (e pode levar segundos/minutos/infinito)?
Existem casos em que os bloqueios não causam esperas? Eu posso imaginar:
- provavelmente
READ UNCOMMITTED
em algumas situações, como não há DDL? - erro é reportado sem esperar...
- ninguém espera, mas primeiro quem faz
commit
ganha, outros falham em seuscommit
Eu revisei a API JDBC : ela menciona literalmente:
SQLTimeoutException - quando o driver determinou que o valor de tempo limite especificado pelo método setQueryTimeout foi excedido e pelo menos tentou cancelar a instrução atualmente em execução
De acordo com os documentos, o tempo limite é detectado no lado do cliente . A API do cliente amplamente usada não tem influência nos tempos limite do lado do servidor ( incluindo causados por bloqueios ). Provavelmente você pode definir algumas propriedades de conexão proprietárias para influenciar o comportamento do banco de dados.
Eu vejo algumas extensões SQL proprietárias, como:
- https://learn.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql
SET LOCK_TIMEOUT timeout_period
- https://www.postgresql.org/docs/13/runtime-config-client.html
set lock_timeout ms
&set statement_timeout ms
Para mim, as esperas de banco de dados devido a bloqueios são uma área cinzenta. Um bloqueio significa uma espera?
Na maioria dos casos, os bloqueios não causam esperas.
Imagine que eu tenha um sistema bancário simples. Para transferir dinheiro da conta A para a conta B, inicio uma transação e adquiro um bloqueio em nível de linha em ambos os registros de conta. Isso me permite executar minhas validações (ou seja, A tem dinheiro suficiente para a transferência, o departamento de fraude não tem um sinalizador em nenhuma das contas, etc.), atualizar ambas as contas para refletir o novo saldo, gerar qualquer registro necessário e confirmar sem se preocupar que alguma outra sessão tenha feito uma alteração em uma ou ambas as contas que deveriam ter impedido a transferência.
A menos que alguma outra sessão apareça na fração de segundo em que estou processando a transferência que tenta bloquear A ou B, os bloqueios que adquiri não geram esperas. Claro, é possível que outra sessão esteja processando uma transação para A no mesmo instante que minha sessão, daí a necessidade do bloqueio. Mas, dadas as milhares de contas e milhões de transações que precisam ser processadas, é muito improvável que haja disputa pelo bloqueio. Particularmente se eu projetar o sistema de forma sensata para que, por exemplo, todas as transações em lote para uma determinada conta sejam processadas por um thread. Se não há contenção, não há esperas.