Súbežný prístup a databázy
Každá zmena — prechod, rollback, zmrazenie, plán, zmena expirácie, adopcia, beh sweepu — prebehne v jednej transakcii na pripojení subjektu:
- Jedna transakcia, jedno poradie zámkov. Každá zmena najprv zamkne riadok subjektu, potom riadky balíka pre tento subjekt a nakoniec zámkové riadky kvót. Zápis stavu je compare-and-swap, takže dve súbežné volania apply() vytvoria jeden riadok histórie; druhé sa zamietne s not_from_current_state.
- check() je len informatívne. Medzi check() a apply() môže konať niekto iný; apply() rozhodne znova pod zámkom.
- Rovnaká databáza. Balík zapisuje svoje riadky na pripojení subjektu, takže jeho tabuľky musia existovať v tej istej databáze. Jeden sweep spracuje jedno pripojenie: pre modely na inom pripojení naplánujte lifecycle:sweep --database=<názov> (lifecycle:validate upozorní, keď chýba).
- MySQL/MariaDB. Na READ COMMITTED beží len transakcia, ktorá počíta kvótu — prechod alebo naplánovaný prechod do stavu s kvótou, prípadne rollback v definícii s kvótami — aby počet za zámkom kvóty videl commit predchádzajúceho držiteľa. Všetko ostatné (vytvorenie modelu, ostatné prechody, zmrazenia, plány, zmeny expirácie, adopcia) si ponechá vašu úroveň izolácie. Handlery, hooky a listenery prechodu s kvótou bežia v tejto transakcii s READ COMMITTED. READ COMMITTED vyžaduje binárne logovanie typu row alebo mixed: s binlog_format=STATEMENT vyhodí prechod s kvótou InvalidLifecycleConfigurationException s návodom na opravu.
- Vypnutie. Nastavte transactions.mysql_read_committed na false (LIFECYCLE_MYSQL_READ_COMMITTED=false), ak chcete vašu izoláciu ponechať aj pre kvóty: počet potom použije zamykacie čítania, ktoré nikdy nepustia viac ako kvótu, no pri náporoch do jedného scope môžu skončiť deadlockom (zopakuje sa, potom vyhodí výnimku). Vo vašej vlastnej transakcii zostáva vždy vaša úroveň izolácie a počty kvót používajú zamykacie čítania.
- PostgreSQL s predvoleným READ COMMITTED je plne podporovaný; pri REPEATABLE READ kvóty zaručené nie sú.
- Deadlocky sa zopakujú transactions.attempts-krát, ak transakciu otvoril balík. Vo vašej transakcii Laravel vnorenú úroveň zopakovať nevie: chyba sa prejaví a vaša transakcia je stratená. Externé vedľajšie efekty držte v listeneroch po commite.
- Hromadné zápisy (Model::query()->update(), čisté SQL) obchádzajú engine a prevezmú sa neskôr — pozri Striktné zápisy a drift.
- Octane a fronty. Skompilované definície sú nemenné a zdieľané; manažér nedrží žiadny stav a akcie, guardy, handlery, Gate, rate limiter aj auth získava z aktuálneho kontajnera pri každom volaní (aj keď vznikol pri boote); allowDirectWrites() platí v rámci requestu alebo jobu.
Compare-and-swap
Zápis stavu je jeden podmienený update odoslaný bez globálnych scopes. Ak neovplyvní žiadny riadok, vyhral iný zapisovateľ: vyhodí sa ConcurrentTransitionException a všetko sa vráti:
UPDATE <table> SET <attr> = :to [, <stamps>] [, updated_at]
WHERE <key> = :id AND <attr> = :fromDuplicitné idempotentné kľúče, dva sweepy nad tými istými splatnými riadkami aj dva súbežné rollbacky jedného riadku rozhodne zámok subjektu a unikátny index — jeden vyhrá a nič sa neaplikuje dvakrát.
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 kryptomienOdoslaní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.