NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Tags for Laravel

Súbežné zápisy a integrita

Dvaja ľudia, ktorí ukladajú v tej istej chvíli, nikdy nevytvoria duplicitné štítky, neporušia limit typu, nepripoja zmazaný štítok ani nepokazia počet použití. Každé meniace volanie beží v transakcii na spojení modelu štítku; vonkajšia transakcia pri deadlocku zopakuje pokus trikrát a pri každom pokuse načíta riadky znova a udalosti sa spustia až po potvrdení vonkajšej transakcie. Vo vašej vlastnej transakcii sa zápis k nej pripojí a neopakuje sa — Laravel vnorenú transakciu nikdy neopakuje, takže rozhoduje vaša vonkajšia transakcia.

Poradie zámkov

Každý zápis zamyká v pevnom poradí a zámky riadkov štítkov berie jedným vzostupným prechodom podľa kľúčov, takže dva zápisy na seba nikdy nečakajú v kruhu:

ZápisZámky, v poradí
attach / detach / sync / clearPri názvoch voľného stromového typu najprv zámok tohto stromu. Potom vlastný riadok modelu, aby každé ďalšie čítanie videlo potvrdený zápis predchádzajúceho zapisovateľa a limit aj sync platili. Potom jeden prechod uzamkne každý riadok štítku, ktorého sa zápis dotkne — pomenované štítky, nesené štítky, ktoré odpája (vo vašej transakcii všetky nesené), a každý riadok, ktorý môže nový názov zmeniť: držiteľov slugov a v strome rodiča a podstrom zmazaného držiteľa. Nové voľné štítky vznikajú v savepointoch so zamykajúcim opätovným čítaním, pri štítkoch na pripojenie sa znova overí, že sú živé, a odpojenie znova prečíta, ktoré priradenia ešte nesie — len tie odstráni, zaráta a ohlási.
… vo vašej vlastnej transakciiNajprv sa uzamknú riadky štítkov, na ktoré ukazujú riadky spojovacej tabuľky modelu (podľa vašej snímky), a štítky, ktoré pripája; potom sa riadky spojovacej tabuľky prečítajú zamykajúcim čítaním, ktoré vždy vidí najnovšie potvrdené riadky, a štítok, ktorý odhalil novší riadok, sa uzamkne naposledy. Riadky štítkov pred riadkami spojovacej tabuľky — v tom istom poradí zamyká zmazanie aj obnova štítku.
Vytvorenie v strome (aj koreň a znovu vytvorený názov), presun, zoradenie, zmazanie s deťmi, obnovaNajprv riadok tag_locks stromu (jeden na typ a rozsah); potom jedným vzostupným prechodom každý riadok štítku, o ktorom zápis rozhoduje alebo ktorý mení — samotný štítok, jeho starého a nového rodiča, podstrom, súrodencov posunutých pozíciou, zmazaný štítok, ktorý názov vráti. Vo vašej transakcii sa tieto riadky potom čítajú zamykajúcim čítaním.
Premenovanie / úpravaRiadok štítku a držitelia každého slugu, ktorý môže zmena prevziať, jedným prechodom v poradí kľúčov.
tags:repair --pathsStrom po strome, vo vnútri zámku daného stromu.
tags:repair --countsDávky po 500 štítkoch; každá pred počítaním uzamkne svoje riadky štítkov v poradí kľúčov.

Keďže riadok modelu je prvý, aplikácia, ktorá v rámci vlastnej transakcie uzamkne model a potom pripojí nový názov, sa s balíkom nezablokuje. A keďže zápis štítkov vo vašej transakcii zamyká riadky štítkov pred riadkami spojovacej tabuľky, DB::transaction(fn () => $event->syncTags($labels, 'label')) sa nikdy nezablokuje so správcom, ktorý jedno z týchto označení maže.

Kedy môže deadlock ešte nastať

Databáza jednu stranu preruší; zápis vo vlastnej transakcii sa zopakuje, transakciu, ktorú ste otvorili vy, opakujete sami:

  • vo vašej transakcii štítok, ktorý k tomu istému modelu pripojila iná požiadavka až po vytvorení vašej snímky a ktorý sa práve v tej chvíli maže;
  • vo vašej transakcii zápis do stromu a zápis štítkov na dvoch štítkoch toho stromu, keď iná požiadavka po vytvorení vašej snímky presunula riadok do množiny zápisu do stromu — prechod číta množinu z tejto snímky a novší riadok sa uzamkne, až keď k nemu zápis dôjde;
  • voľný názov, ktorého zmazaný držiteľ má ešte zvyšné priradenie na tom istom modeli (obyčajné $tag->delete()), znovu vytvorený vo vašej transakcii v čase, keď správca tento štítok obnovuje.

Čo je zaručené

  • Dve súbežné attachTags() na type s jedným štítkom nikdy nenechajú modelu dve kategórie.
  • Dve súbežné vytvorenia toho istého názvu skončia jedným štítkom a DuplicateTagException — pri findOrCreate() dostanú obe ten istý štítok.
  • Pripojenie súbežné so zmazaním toho istého štítku nikdy nepripojí zmazaný štítok (TagNotFoundException, „The tag is deleted.“).
  • Počty použití sa upravujú v tej istej transakcii ako riadky spojovacej tabuľky, presne o zapísané riadky, takže zostávajú presné; presné je aj prepočítanie opravou počas živej prevádzky.
  • Presuny, zoradenia a mazanie podstromov sa v jednom strome nikdy neprekrývajú a vo vašej transakcii vidia strom tak, ako ho nechal zapisovateľ, na ktorého čakali: žiadny cyklus rodičov, žiadne prehliadnuté nové dieťa, žiadna zastaraná cesta.
  • Odpojenie, ktoré čakalo na riadok štítku držaný mazaním, zaráta len priradenia, ktoré naozaj odstránilo.

MySQL a PostgreSQL

  • Vkladanie je obyčajný INSERT, nikdy INSERT IGNORE, ktorý by aj chybu cudzieho kľúča či orezania premenil na upozornenie; neúspešné vloženie beží v savepointe, takže PostgreSQL ponechá vonkajšiu transakciu použiteľnú.
  • Vo vnútri transakcie, ktorú ste otvorili — a ktorá si mohla snímku REPEATABLE READ v MySQL vziať skôr —, sa aktuálne priradenia aj každý riadok stromu, o ktorom zápis do stromu rozhoduje, čítajú zamykajúcim čítaním; agregácia sa číta ako najvyšší riadok, pretože PostgreSQL pri nej FOR UPDATE odmieta.
  • Posledná pozícia súrodenca je jediné zostávajúce obyčajné čítanie: zastaraná hodnota len zrovná dvoch súrodencov, ktorí sa potom zoradia podľa pozície a kľúča.
  • Kľúče zvonka sa pred akýmkoľvek SQL overia proti nakonfigurovanému typu kľúča — vrátane kľúča bigint mimo 64-bitového rozsahu —, pretože PostgreSQL by na nesúhlasiaci kľúč odpovedal chybou a MySQL by ho potichu pretypoval.

Každá udalosť implementuje ShouldDispatchAfterCommit: listenery sa spustia až po potvrdení zmeny a odvolaný zápis neohlási nič. Balík je testovaný proti PostgreSQL aj MySQL s paralelnými zápismi.

Zápisy mimo balíka

Hromadné mazanie modelov so štítkami, obyčajné $tag->delete(), import cez SQL či ručne upravené parent_id tieto záruky obídu. tags:doctor nájde, čo po nich zostane, a tags:repair to opraví — cesty a hĺbky, kľúče rozsahu, osirotené priradenia, priradenia na zmazaných štítkoch a počty použití — po dávkach, bezpečne aj pri živej prevádzke (pozrite Artisan príkazy).

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.