atomické inserty vs. zamknutí tabulky
- kedlas
- Člen | 6
Ahoj, protože se zde nachází mnoho chytrých hlav, rozhodl jsem se vás požádat o radu.
Řeším následující problém. Mám rezervační systém, ve kterém lze rezervovat sedačky na představení a chci předejít problému, kdy 2 uživatelé ve stejný čas chtějí rezervovat stejné sedačky (nebo alespoň jednu z vybraných sedaček chtějí oba), Např uživatel A chce zarezervovat sedačky č. 1,2 a 3 a uživatel B chce sedačky 3 a 4.
Pokud bych to dělal klasickými Inserty do MySQL po sobě jdoucími, může se stát že uživatel A uloží do DB záznamy pro rezervaci sedaček 1 a 2, ale třetí sedačka už mu neprojde, protože mezitím si ji zarezervoval uživatel B.
Chci tedy docílit toho, abych měl nějakou množinu INsertů a buď se provedly všechny nebo žádný.
Na googlu jsem si našel buď to, že lze tabulku zamknout a provést inserty pomocí příkazů
LOCK TABLE t AS myalias READ;
provést Inserty;
UNLOCK TABLE...
spíš by mě ale zajímalo, jestli nelze nějak místo zamykání zabalit inserty do jednoho atomického celku. Případně jestli na to už v Nette něco není.
Jaké řešení je podle vás lepší, nebo máte ještě nějaké jiné?
- h4kuna
- Backer | 740
Atomicitu řeší transakce a mám pocit že zámky mimo transakce nefungují. To co tady máš je zámek celý tabulky, ale taky existují řádkové zámky SELECT … FOR UPDATE. Tj když dva ve stejnou dobu budou ukládat rozdílná sedadla tak zámkem tabulky je donutíš že se to bude zpracovávat v sérii. Pokud využiješ řádkový zámek tak se zpracují paralelně.
Toto celé v transakci
SELECT ... WHERE sedadla IN (1, 2, 3) FOR UPDATE;
INSERT uzivatele_maji_sedadla (...)
UPDATE sedadla SET (...);
EDIT:
Napadá mě další řešení, že musíš mít tabulku představení, sedadla a
tyto dvě spojuje další tabulka a když do ni dáš složený klíč nad
sedadla_id a predstaveni_id jako unique, tak se ti nestane že by dva objednali
stejný sedadlo. Pak jen správně reagovat na exception.
Editoval h4kuna (17. 1. 2014 9:52)