5.1 Jeksa Agung bisa ngetokake saka simultaneity

Ayo dadi miwiti karo teori sethitik adoh.

Sembarang sistem informasi (utawa mung, aplikasi) sing digawe programer kasusun saka sawetara pamblokiran khas, saben kang nyedhiyani bagean saka fungsi perlu. Contone, cache digunakake kanggo ngelingi asil operasi intensif sumber daya kanggo mesthekake maca data sing luwih cepet dening klien, alat pangolahan stream ngidini sampeyan ngirim pesen menyang komponen liyane kanggo pangolahan asinkron, lan alat pangolahan batch digunakake kanggo " rake" volume akumulasi data kanthi periodisitas. .

Lan ing meh kabeh aplikasi, database (DB) melu kanthi cara siji utawa liyane, sing biasane nindakake rong fungsi: nyimpen data nalika ditampa saka sampeyan lan banjur menehi sampeyan yen dijaluk. Jarang ana sing mikir nggawe database dhewe, amarga wis akeh solusi sing wis siap. Nanging kepiye sampeyan milih sing cocog kanggo aplikasi sampeyan?

Dadi, bayangake yen sampeyan wis nulis aplikasi kanthi antarmuka seluler sing ngidini sampeyan mbukak dhaptar tugas sing wis disimpen sadurunge ing omah - yaiku, maca saka database, lan nambah tugas anyar, uga prioritas saben spesifik. tugas - saka 1 (paling dhuwur) kanggo 3 (paling). Contone, aplikasi seluler sampeyan mung digunakake dening wong siji. Nanging saiki sampeyan wis wani ngandhani ibu babagan kreasi sampeyan, lan saiki dheweke wis dadi pangguna biasa nomer loro. Apa sing kedadeyan yen sampeyan mutusake ing wektu sing padha, ing milidetik sing padha, kanggo nyetel sawetara tugas - "kumbah jendhela" - kanthi prioritas sing beda?

Ing istilah profesional, pitakon database sampeyan lan ibu bisa dianggep minangka 2 proses sing nggawe pitakon menyang database. Proses minangka entitas ing program komputer sing bisa mlaku ing siji utawa luwih utas. Biasane, proses nduweni gambar kode mesin, memori, konteks, lan sumber daya liyane. Ing tembung liyane, proses bisa ditondoi minangka eksekusi instruksi program ing prosesor. Nalika aplikasi sampeyan nggawe panjaluk menyang database, kita ngomong babagan kasunyatan manawa database sampeyan ngolah panjaluk sing ditampa liwat jaringan saka siji proses. Yen ana rong pangguna sing lungguh ing aplikasi kasebut bebarengan, mula bisa uga ana rong proses ing wektu tartamtu.

Nalika sawetara proses nggawe panjalukan kanggo database, nemokake ing negara tartamtu. Sistem stateful minangka sistem sing ngelingi acara sadurunge lan nyimpen sawetara informasi, sing diarani "negara". Variabel sing diumumake minangka integerbisa nduweni status 0, 1, 2, utawa ngomong 42. Mutex (mutual exclusion) nduweni rong negara: dikunci utawa ora dikunci , kaya semafor biner ("dibutuhake" vs. "dibebasake") lan umume binar (biner) jinis data lan variabel sing mung bisa duwe rong negara - 1 utawa 0.

Adhedhasar konsep negara, sawetara struktur matématika lan rekayasa adhedhasar, kayata otomatis otomatis - model sing nduweni siji input lan siji output lan ana ing salah sawijining set negara sing winates ing saben wektu - lan "negara". "pola desain, ing endi obyek ngganti prilaku gumantung ing negara internal (contone, gumantung apa nilai diutus kanggo siji utawa variabel liyane).

Dadi, umume obyek ing jagad mesin duwe sawetara negara sing bisa diganti kanthi wektu: pipa kita, sing ngolah paket data sing gedhe, nggawe kesalahan lan gagal, utawa properti obyek Dompet, sing nyimpen jumlah dhuwit sing isih ana ing pangguna. akun, owah-owahan sawise kuitansi payroll.

Transisi ("transisi") saka negara siji menyang negara liyane - ngomong, saka proses nganti gagal - diarani operasi. Mbokmenawa, kabeh wong ngerti operasi CRUD - create, read, update, deleteutawa cara HTTP sing padha - POST, GET, PUT, DELETE. Nanging programer asring menehi jeneng liya kanggo operasi ing kode, amarga operasi bisa luwih rumit tinimbang mung maca nilai tartamtu saka database - uga bisa mriksa data, lan banjur operasi kita, kang wis njupuk wangun fungsi. bakal disebut, contone,, Lan validate()sing nindakake iki operasi-fungsi? pangolahan wis diterangake.

A little liyane, lan sampeyan bakal ngerti kok aku njlèntrèhaké istilah ing rinci kuwi!

Sembarang operasi - dadi fungsi, utawa, ing sistem sing disebarake, ngirim panjalukan menyang server liyane - nduweni 2 sifat: wektu panyuwunan lan wektu rampung (wektu rampung) , sing bakal luwih gedhe tinimbang wektu panyuwunan (peneliti saka Jepsen). nerusake saka asumsi teoretis yen loro cap wektu kasebut bakal diwenehi jam khayalan, disinkronake kanthi lengkap, lan kasedhiya sacara global).

Ayo bayangake aplikasi dhaptar sing kudu ditindakake. Sampeyan nggawe panjalukan kanggo database liwat antarmuka seluler ing 14:00:00.014, lan ibu ing 13:59:59.678(yaiku, 336 milliseconds sadurunge) nganyari dhaptar tugas liwat antarmuka sing padha, nambahake ngumbah piring. Ngelingi wektu tundha jaringan lan kemungkinan antrian tugas kanggo database sampeyan, yen, saliyane sampeyan lan ibu, kabeh kanca ibu sampeyan uga nggunakake aplikasi sampeyan, database bisa nglakokake panjaluk ibu sawise ngolah sampeyan. Ing tembung liyane, ana kemungkinan loro panjalukmu, uga panjaluk saka pacar ibumu, bakal dikirim menyang data sing padha bebarengan (bebarengan).

Dadi kita wis teka ing istilah sing paling penting ing bidang database lan aplikasi sing disebarake - concurrency. Apa tegese simultan saka rong operasi? Yen sawetara operasi T1 lan sawetara operasi T2 diwenehi, banjur:

  • T1 bisa diwiwiti sadurunge wektu wiwitan eksekusi T2, lan rampung antarane wiwitan lan pungkasan wektu T2
  • T2 bisa diwiwiti sadurunge wektu wiwitan T1, lan rampung antarane wiwitan lan pungkasan T1
  • T1 bisa diwiwiti lan rampung ing antarane wektu wiwitan lan pungkasan eksekusi T1
  • lan skenario liyane ing ngendi T1 lan T2 duwe sawetara wektu eksekusi umum

Cetha yen ing kerangka kuliah iki, kita ngomong utamane babagan pitakon sing mlebu ing database lan kepiye sistem manajemen database ngerteni pitakon kasebut, nanging istilah konkurensi penting, contone, ing konteks sistem operasi. Aku ora bakal nyimpang adoh banget saka topik artikel iki, nanging aku mikir penting kanggo sebutno yen concurrency sing kita gunakake ing kene ora ana hubungane karo dilema concurrency lan concurrency lan bedane, sing dibahas ing konteks sistem operasi lan kinerja dhuwur. Paralelisme minangka salah sawijining cara kanggo nggayuh konkurensi ing lingkungan kanthi macem-macem inti, prosesor, utawa komputer. Kita ngomong babagan concurrency ing pangertèn akses simultan saka macem-macem pangolahan kanggo data umum.

Lan apa, nyatane, bisa salah, kanthi teoritis?

Nalika nggarap data sing dienggo bareng, akeh masalah sing ana gandhengane karo konkurensi, uga disebut "kondisi balapan", bisa kedadeyan. Masalah pisanan kedadeyan nalika proses nampa data sing ora kudu ditampa: data ora lengkap, sementara, dibatalake, utawa data "salah". Masalah kapindho yaiku nalika proses nampa data basi, yaiku, data sing ora cocog karo kahanan database sing disimpen pungkasan. Ayo dadi sawetara aplikasi wis mbatalake dhuwit saka akun pangguna karo imbangan nul, amarga database bali status akun kanggo aplikasi, ora njupuk menyang akun mundur total dhuwit saka iku, kang kedaden mung saperangan milliseconds ago. Kahanane kaya ngono ta?

5.2 Transaksi Teka kanggo Nylametake Kita

Kanggo ngatasi masalah kasebut, konsep transaksi muncul - klompok operasi sekuensial tartamtu (owah-owahan negara) kanthi basis data, yaiku operasi tunggal sing logis. Aku bakal menehi conto maneh karo bank - lan ora kanthi kasempatan, amarga konsep transaksi katon, mesthine, ing konteks nggarap dhuwit. Conto klasik saka transaksi yaiku transfer dhuwit saka akun bank menyang akun liyane: sampeyan kudu mbatalake jumlah kasebut saka akun sumber lan banjur setor menyang akun target.

Kanggo nindakake transaksi iki, aplikasi kudu nindakake sawetara tumindak ing basis data: mriksa imbangan pangirim, mblokir jumlah ing akun pangirim, nambah jumlah menyang akun panampa, lan nyuda jumlah saka pangirim. Ana sawetara syarat kanggo transaksi kasebut. Contone, aplikasi ora bisa nampa informasi sing wis lawas utawa salah babagan imbangan - contone, yen ing wektu sing padha transaksi paralel rampung kanthi kesalahan separo, lan dana ora didebit saka akun kasebut - lan aplikasi kita wis nampa informasi. yen dana wis dibusak.

Kanggo ngatasi masalah iki, properti transaksi kasebut minangka "isolasi" diarani: transaksi kita ditindakake kaya-kaya ora ana transaksi liyane sing ditindakake ing wektu sing padha. Basis data kita nindakake operasi bebarengan kaya-kaya nglakokake siji-sijine, kanthi urutan - nyatane, tingkat isolasi paling dhuwur diarani Strict Serializable . Ya, sing paling dhuwur, tegese ana sawetara level.

"Stop," sampeyan ngomong. Cekel jaran, Pak.

Ayo elinga carane aku nerangake yen saben operasi duwe wektu telpon lan wektu eksekusi. Kanggo penak, sampeyan bisa nimbang nelpon lan eksekusi minangka 2 tumindak. Banjur dhaptar sing diurutake kabeh telpon lan tumindak eksekusi bisa diarani riwayat database. Banjur tingkat isolasi transaksi minangka sakumpulan riwayat. Kita nggunakake tingkat isolasi kanggo nemtokake crita sing "apik". Nalika kita ngomong yen crita "ngrusak serializability" utawa "ora serializable", kita ateges sing crita ora ing pesawat saka crita serializable.

Kanggo nggawe cetha apa jenis crita kita ngomong bab, aku bakal menehi conto. Contone, ana jenis sejarah - maca intermediate . Iki kedadeyan nalika transaksi A diidini maca data saka baris sing wis diowahi dening transaksi B liyane sing mlaku lan durung dileksanakake ("ora setya") - yaiku, nyatane, owah-owahan durung rampung ditindakake dening transaksi B, lan bisa sawayah-wayah mbatalake. Lan, contone, maca sing dibatalake mung conto karo transaksi penarikan sing dibatalake

Ana sawetara kemungkinan anomali. Tegese, anomali minangka sawetara negara data sing ora dikarepake sing bisa kedadeyan sajrone akses kompetitif menyang database. Lan kanggo ngindhari kahanan sing ora dikarepake, database nggunakake tingkat isolasi sing beda - yaiku, tingkat perlindungan data sing beda saka negara sing ora dikarepake. Tingkat kasebut (4 potongan) kadhaptar ing standar ANSI SQL-92.

Dhèskripsi saka tingkat iki katon samar kanggo sawetara peneliti, lan padha kurban dhewe, luwih rinci, klasifikasi. Aku menehi saran supaya menehi perhatian marang Jepsen sing wis kasebut, uga proyek Hermitage, sing tujuane kanggo njlentrehake persis apa tingkat isolasi sing ditawakake DBMS tartamtu, kayata MySQL utawa PostgreSQL. Yen sampeyan mbukak file saka gudang iki, sampeyan bisa ndeleng apa urutan printah SQL digunakake kanggo test database kanggo anomali tartamtu, lan sampeyan bisa nindakake soko padha kanggo database sing kasengsem ing). Mangkene salah sawijining conto saka repositori supaya sampeyan tetep kasengsem:

-- Database: MySQL

-- Setup before test
create table test (id int primary key, value int) engine=innodb;
insert into test (id, value) values (1, 10), (2, 20);

-- Test the "read uncommited" isolation level on the "Intermediate Reads" (G1b) anomaly
set session transaction isolation level read uncommitted; begin; -- T1
set session transaction isolation level read uncommitted; begin; -- T2
update test set value = 101 where id = 1; -- T1
select * from test; -- T2. Shows 1 => 101
update test set value = 11 where id = 1; -- T1
commit; -- T1
select * from test; -- T2. Now shows 1 => 11
commit; -- T2

-- Result: doesn't prevent G1b

Penting kanggo mangerteni yen kanggo database sing padha, minangka aturan, sampeyan bisa milih salah siji saka sawetara jinis isolasi. Napa ora milih insulasi sing paling kuat? Amarga, kaya kabeh ing ilmu komputer, tingkat isolasi sing dipilih kudu cocog karo trade-off sing kita siap - ing kasus iki, trade-off ing kacepetan eksekusi: sing luwih kuat tingkat isolasi, sing luwih alon panjalukan bakal. diproses. Kanggo ngerti apa tingkat isolasi sing sampeyan butuhake, sampeyan kudu ngerti syarat aplikasi sampeyan, lan ngerti apa database sing sampeyan pilih nawakake level iki, sampeyan kudu ndeleng dokumentasi - kanggo umume aplikasi iki bakal cukup, nanging yen sampeyan duwe sawetara syarat utamané nyenyet, iku luwih apik kanggo ngatur test kaya apa wong lanang saka project Hermitage.

5.3 "I" lan huruf liyane ing ACID

Isolasi yaiku apa sing dimaksudake wong nalika ngomong babagan ACID ing umum. Lan kanggo alasan iki aku miwiti analisis akronim iki kanthi ngisolasi, lan ora mlaku kanthi urutan, kaya sing biasane ditindakake dening wong-wong sing nyoba nerangake konsep iki. Saiki ayo deleng telung huruf sing isih ana.

Kelingan maneh conto kita karo transfer bank. Transaksi kanggo nransfer dana saka siji akun menyang akun liyane kalebu operasi penarikan saka akun pisanan lan operasi replenishment ing liyane. Yen operasi replenishment saka akun kapindho gagal, sampeyan mbokmenawa ora pengin operasi mundur total saka akun pisanan kelakon. Ing tembung liyane, salah siji transaksi sukses rampung, utawa ora kelakon ing kabeh, nanging ora bisa digawe mung kanggo sawetara bagean. Sifat iki diarani "atomicity", lan minangka "A" ing ACID.

Nalika transaksi kita kaleksanan, banjur, kaya operasi sembarang, iku nransfer database saka siji negara bener kanggo liyane. Sawetara database nawakake sing diarani watesan - yaiku, aturan sing ditrapake kanggo data sing disimpen, contone, babagan kunci primer utawa sekunder, indeks, nilai standar, jinis kolom, lsp. Dadi, nalika nggawe transaksi, kita kudu yakin manawa kabeh kendala kasebut bakal ditindakake.

Jaminan iki diarani "konsistensi" lan layang Cing ACID (ora bakal bingung karo konsistensi saka jagad aplikasi sing disebarake, sing bakal dibahas mengko). Aku bakal menehi conto sing jelas kanggo konsistensi ing pangertèn ACID: aplikasi kanggo toko online pengin nambah ordersbaris ing meja, lan ID saka meja product_idbakal dituduhake ing kolom - khas .productsforeign key

Yen prodhuk kasebut, ujar, dicopot saka macem-macem, lan, mula, saka database, mula operasi sisipan baris ora bakal kedadeyan, lan kita bakal entuk kesalahan. Jaminan iki, dibandhingake karo wong liya, rada adoh, miturut pendapatku - yen mung amarga panggunaan kendala aktif saka basis data tegese mindhah tanggung jawab kanggo data kasebut (uga owah-owahan sebagian logika bisnis, yen kita ngomong babagan kendala kayata CHECK ) saka aplikasi menyang database, sing, lagi ngomong saiki, mung dadi.

Lan pungkasanipun, tetep D- "resistance" (daya tahan). Gagal sistem utawa kegagalan liyane ora bakal nyebabake mundhut asil transaksi utawa isi database. Yaiku, yen database mangsuli yen transaksi kasebut sukses, mula data kasebut direkam ing memori non-molah malih - contone, ing hard disk. Iki, kanthi cara, ora ateges sampeyan bakal langsung ndeleng data ing panjalukan maca sabanjure.

Mung dina liyane, aku nggarap DynamoDB saka AWS (Layanan Web Amazon), lan ngirim sawetara data kanggo disimpen, lan sawise nampa jawaban HTTP 200(OK), utawa kaya, aku mutusaké kanggo mriksa - lan ora weruh iki. data ing database kanggo sabanjure 10 Detik. Yaiku, DynamoDB nindakake dataku, nanging ora kabeh simpul langsung disinkronake kanggo entuk salinan data paling anyar (sanajan bisa uga ana ing cache). Kene maneh menek menyang wilayah konsistensi ing konteks sistem mbagekke, nanging wektu kanggo pirembagan bab iku isih durung teka.

Dadi saiki kita ngerti apa jaminan ACID. Lan kita malah ngerti kok padha migunani. Nanging apa kita butuh banget ing saben aplikasi? Lan yen ora, kapan persis? Apa kabeh DB nawakake jaminan kasebut, lan yen ora, apa sing ditawakake?