Middle
Co jsou zámky v kontextu práce s databázemi a proč jsou nutné?
sobes.tech AI
Odpověď od AI
Zámky v databázi jsou mechanismy používané k řízení přístupu více uživatelů nebo procesů ke stejným datům současně. Zabraňují konfliktům a udržují integritu dat v konkurenčním prostředí.
Jsou nezbytné pro řešení následujících problémů:
- Race Conditions: Situace, kdy pořadí provádění operací ovlivňuje konečný výsledek. Zámky zajišťují, že operace budou prováděny sekvenčně nebo v bezpečném pořadí.
- Inconsistent Reads: Jeden proces čte data, zatímco jiný je mění, což může vést k získání mezistavů nebo neúplných dat. Zámky tomu mohou zabránit.
- Lost Updates: Dva procesy čtou stejná data, každý je mění a poté ukládá. Poslední uložení přepíše změny prvního, čímž je ztratí. Zámky pomáhají zabránit ztrátě změn.
- Phantom Reads: V rámci jedné transakce opakovaný dotaz vrací jiný soubor řádků, protože jiný proces přidal nebo odstranil řádky odpovídající podmínkám dotazu.
Hlavní typy zámků:
- Sdílený (Shared/Read Lock): Umožňuje více transakcím číst stejná data současně. Neumožňuje zápisové zámky na stejná data.
- Exkluzivní (Exclusive/Write Lock): Poskytuje monopolní přístup k datům. Pouze jedna transakce může mít exkluzivní zámek na určitá data v daném okamžiku. Neumožňuje ani čtení, ani zápisové zámky na stejná data.
Zámky mohou být aplikovány na různých úrovních:
- Úroveň databáze: Zamkne celou databázi. Zřídka používané.
- Úroveň tabulky: Zamkne celou tabulku. Méně detailní, může snížit konkurenceschopnost.
- Úroveň řádku: Zamkne samostatný řádek. Více detailní, podporuje vysokou konkurenceschopnost, ale může vyžadovat více zdrojů.
- Úroveň stránky: Zamkne stránku dat (jednotka úložiště v DBMS obsahující několik řádků). Kompromis mezi zamknutím tabulky a řádku.
Implementace zámků závisí na konkrétním DBMS (například InnoDB a MyISAM v MySQL mají odlišné strategie zámků, PostgreSQL atd.). V PHP se často používají transakce k řízení zámků.
-- Příklad použití transakce a zámku v SQL
START TRANSACTION;
SELECT balance FROM accounts WHERE account_id = 123 FOR UPDATE;
-- FOR UPDATE klade exkluzivní zámek na vybraný řádek
UPDATE accounts SET balance = balance - 100 WHERE account_id = 123;
COMMIT;
-- Nebo ROLLBACK při chybě