Ani náhodou. FOR UPDATE
uzamkne pouze tyto řádky , takže další transakce, která se je pokouší uzamknout (pomocí FOR SHARE
, FOR UPDATE
, UPDATE
nebo DELETE
) blokuje, dokud se vaše transakce nepotvrdí nebo nevrátí zpět.
Pokud chcete zámek celé tabulky, který blokuje vkládání/aktualizace/mazání, pravděpodobně budete chtít LOCK TABLE ... IN EXCLUSIVE MODE
.
-
Viz
lock_timeout
nastavení . Toto bylo přidáno ve verzi 9.3 a není k dispozici ve starších verzích.Hrubé aproximace pro starší verze lze dosáhnout pomocí
statement_timeout
, ale to může vést ke zbytečnému rušení výpisů. Pokudstatement_timeout
je 1 s a příkaz čeká 950 ms na zámek, může pak získat zámek a pokračovat, ale bude okamžitě zrušen časovým limitem. Ne to, co chcete.Na úrovni dotazu neexistuje žádný způsob, jak nastavit
lock_timeout
, ale můžete a měl by jen:SET LOCAL lock_timeout = '1s';
poté, co
BEGIN
transakce. -
Existuje prohlášení vypršel časový limit, ale zámky jsou drženy při transakci úroveň. Neexistuje žádná funkce časového limitu transakce.
Pokud spouštíte transakce s jedním výpisem, stačí nastavit
statement_timeout
před spuštěním příkazu, abyste omezili, jak dlouho může běžet. To však není úplně to samé jako omezení doby, po kterou může zámek podržet, protože na zámek může čekat 900 ms z povolených 1s, ve skutečnosti podrží zámek pouze 100 ms a poté bude zrušen časovým limitem. -
Ne. Musíte:
BEGIN; SET LOCAL lock_timeout = '4s'; SELECT ....; COMMIT;
-
SET LOCAL
je k tomu vhodný a preferovaný.V textu dotazu to nelze nijak provést, musí to být samostatný příkaz.
Příspěvek do mailing listu, na který jste odkazovali, je návrhem imaginární syntaxe, která nebyla nikdy implementována (alespoň ve veřejné verzi PostgreSQL) a neexistuje.
V situaci, jako je tato, možná budete chtít zvážit „optimistické řízení souběžnosti“, často nazývané „optimistické zamykání“. Poskytuje vám větší kontrolu nad chováním zamykání za cenu zvýšeného počtu opakování dotazů a potřeby větší aplikační logiky.