Autor | Zpráva | ||
---|---|---|---|
lionel messi Profil |
#1 · Zasláno: 8. 12. 2019, 22:15:24
Zdravím,
pracujem na vlastnom redakčnom systéme a narazil som na nutnosť riešiť atomicitu na úrovni MySQL. Pri tvorbe článku vždy zálohujem v DB aj jeho koncept, čiže každú minútu posielam pomocou AJAXu dotaz na zápis, resp. aktualizáciu údajov v databáze. Po kliknutí na tlačidlo odoslať sa vykoná zodpovedajúca operácia, ktorá publikuje článok (= ak z neho neexistuje koncept, vloží sa nový záznam, ak existuje, nastaví sa stĺpec, ktorý rieši, či je skrytý, alebo publikovaný, zodpovedajúcim spôsobom). Narazil som však na problém s atomicitou – stane sa, že po kliknutí na odoslanie počas spracovania operácie prebehne súčasne aj uloženie konceptu - buď sa uložia dva totožné články (jeden publikovaný a jeden koncept), alebo sa v článku nežiaducim spôsobom zmení nastavenie zverejnenia (skryje sa). Rád by som podobnému správaniu predišiel, a tak mi napadlo vytvoriť transakciu pre dotaz zameraný na ukladanie konceptov. Chcel by som sa spýtať, či ide o dobré riešenie. Nižšie uvádzam dotaz: START TRANSACTION; -- vyberieme najnovší záznam, porovnáme dátum, napíšeme dotaz pre vkladanie SELECT TIMEDIFF(now(), datum) as rozdiel FROM tabulka ORDER BY id DESC LIMIT 1; INSERT INTO tabulka (stlpec1, stlpec2) VALUES (hodnota1, hodnota); -- ak je rozdiel menej než 5 sekúnd, zrušíme transakciu IF rozdiel < '0:00:05' THEN ROLLBACK; -- ak nie, vkladáme dáta ELSE COMMIT; END IF; Na záver by ma ešte zaujímalo, prečo mi PHPMyAdmin podčiarkuje slovo IF ako syntaktickú chybu a tvrdí, že na konci dotazu sa „očakávala ukončovacia úvodzovka“. Podľa tutoriálov na webe ani knihy o SQL totiž syntaktickú chybu nikde nevidím. Vopred veľmi pekne ďakujem za každú radu. |
||
Keeehi Profil |
#2 · Zasláno: 8. 12. 2019, 22:37:21
lionel messi:
Mno, a proč to nevyřešíš už na straně javascriptu? Jakmile klikneš na tlačítko odeslat, tak zrušíš ten timeout co spouští AJAX. A pokud zrovna běží AJAXový požadavek, tak odeslání pozdržíš do té doby, než ten AJAX nedoběhne. Nepřijde mi to nijak složité. Viděl bych to asi takto: var isAjaxRunning = false; var shouldSubmit = false; var ajaxTimer = setInterval(function() { var xhr = new XMLHttpRequest(); xhr.onload = function () { isAjaxRunning = false; if(shouldSubmit) { form.submit(); clearInterval(ajaxTimer); } }; xhr.open('GET', 'https://example.org'); xhr.send(); isAjaxRunning = true; }, 60 * 1000); form.onsubmit = function() { if(isAjaxRunning) { shouldSubmit = true; event.preventDefault(); return; } clearInterval(ajaxTimer); return; } Bude to chtít upravit ale obecnou představu, jak by to asi mělo fungovat z toho dostaneš. Jinak z pohledu UX by to chtělo, pokud ten formulář bude čekat na dokončení AJAX požadavku, aby se tlačítko pro odeslání zneaktivnilo a objevil se tam nějaký spinner, aby bylo jasné, že se to odesílá. |
||
lionel messi Profil |
#3 · Zasláno: 9. 12. 2019, 10:29:34
Keeehi:
„Nepřijde mi to nijak složité. Viděl bych to asi takto:“ Ďakujem. Áno, to bude asi najčistejšie riešenie, ešte sa s tým JS trochu pohrám. Napriek tomu by ma zaujímala aj tá údajná syntaktická chyba v [#1], pretože transakcie budem zrejme beztak potrebovať. :-) |
||
Kajman Profil |
#4 · Zasláno: 9. 12. 2019, 10:48:25
lionel messi:
„tá údajná syntaktická chyba“ Je možné, že to je jen chyba v PHPMyAdmin a tamním vlastním parseru. Ale než kontrolovat čas od posledního uložení, spíše bych s konceptem posílal identifikaci verzi článku, kdy byl ručně uložen a koncept je jeho úprava. Pokud přijde koncept ke starší verzi článku (tedy byla dříve ručně potvrzená rozpracovaná verze tlačítkem), můžete ho např. ignorovat. |
||
ttttt Profil * |
#5 · Zasláno: 9. 12. 2019, 12:21:29
lionel messi:
„Napriek tomu by ma zaujímala aj tá údajná syntaktická chyba v [#1], pretože transakcie budem zrejme beztak potrebovať. :-)“ PHPMyAdmin nejspíš příkazy vykonává jako dotazy. IF je konstrukce, kterou lze použít jen v uložené proceduře, triggeru nebo události (event), není to dotaz (query).
Ten SQL kód má několik problémů * rozdiel je potřeba uložit do proměnné pomocí SELECT INTO * INSERT by mohl být až v ELSE větvi, po vyhodnocení podmínky * jestli MySQL umí unikátní funkční index, dá se to celé vyřešit tím, že se nadefinuje, že unikátní index na časem zaokrouhleným na 5 vteřin A raději řešení, co navrhoval Kajman. |
||
Časová prodleva: 5 let
|
0