Fitur mékanisme internal PostgreSQL ngamungkinkeun éta gancang pisan dina sababaraha kaayaan sareng "henteu gancang pisan" dina anu sanés. Dinten ieu kami bakal difokuskeun conto klasik konflik antara kumaha DBMS jalan sareng naon anu dilakukeun ku pamekar - UPDATE vs prinsip MVCC.
Carita singket ti
Lamun baris dirobah ku paréntah UPDATE, dua operasi sabenerna dipigawé: DELETE jeung INSERT. DI Vérsi string ayeuna xmax diatur sarua jeung jumlah transaksi anu dipigawé UPDATE. Lajeng dijieun versi anyar garis sarua; nilai xmin na coincides jeung nilai xmax tina versi saméméhna.
Sababaraha waktu sanggeus urus ieu réngsé, versi heubeul atawa anyar, gumantung kana COMMIT/ROOLBACK
, bakal dipikawanoh "maot" (tuples maot) nalika ngaliwat VACUUM
nurutkeun tabel sarta diberesihan.
Tapi ieu moal lumangsung langsung, tapi masalah jeung "maot" bisa kaala pisan gancang - diulang atawa
#1: Abdi resep mindahkeun éta
Sebutkeun metode logika bisnis anjeun damel nyalira, sareng ujug-ujug sadar yén éta peryogi pikeun ngapdet widang X dina sababaraha catetan:
UPDATE tbl SET X = <newX> WHERE pk = $1;
Lajeng, sakumaha palaksanaan progresses, tétéla yén widang Y ogé kudu diropéa:
UPDATE tbl SET Y = <newY> WHERE pk = $1;
... lajeng ogé Z - naha runtah waktu dina trifles?
UPDATE tbl SET Z = <newZ> WHERE pk = $1;
Sabaraha vérsi catetan ieu ayeuna urang gaduh dina pangkalan data? yeuh, 4 lembar! Tina ieu, hiji relevan, sareng 3 kedah dibersihkeun saatos anjeun ku [otomatis] VACUUM.
Ulah ngalakukeun cara kieu! Paké ngamutahirkeun sadaya widang dina hiji pamundut - ampir sok logika metode tiasa dirobih sapertos kieu:
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
# 2: Pamakéan béda ti, Lukas!
Janten, anjeun masih hoyong
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;
A pamundut di kira formulir ieu lumangsung rada mindeng sarta ampir sok teu ngeusian hiji widang anyar kosong, tapi pikeun ngabenerkeun sababaraha kasalahan dina data. Dina waktu nu sarua, manéhna sorangan kabeneran data anu aya henteu dipertimbangkeun pisan - tapi sia! Nyaéta, rékamanna ditulis deui, sanaos ngandung persis naon anu dipikahoyong - tapi naha? Hayu urang ngalereskeun:
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;
Seueur jalma henteu sadar kana ayana operator anu saé sapertos kitu, janten ieu mangrupikeun lambaran curang IS DISTINCT FROM
sareng operator logis séjén pikeun ngabantosan:
... sarta saeutik ngeunaan operasi on kompléks ROW()
-ekspresi:
#3: Kuring mikawanoh sweetheart kuring ku ... blocking
keur diluncurkeun dua prosés paralel idéntik, anu masing-masing nyobian nyirian éntri yén éta "dina kamajuan":
UPDATE tbl SET processing = TRUE WHERE pk = $1;
Sanaos prosés ieu leres-leres ngalakukeun hal anu mandiri, tapi dina ID anu sami, klien kadua bakal "dikonci" dina pamundut ieu dugi ka urus munggaran réngsé.
Solusi # 1: tugas diréduksi jadi saméméhna
Hayu urang tambahkeun deui IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
Dina formulir ieu, pamundut kadua saukur moal ngarobah nanaon dina database, sagalana geus sakumaha kuduna - kituna, blocking moal lumangsung. Salajengna, urang ngolah kanyataan "teu manggihan" catetan dina algoritma dilarapkeun.
Solusi # 2: Konci piwuruk
Topik anu ageung pikeun tulisan anu misah, dimana anjeun tiasa maca
Solusi # 3: nelepon bodo
Tapi ieu téh kahayang kudu lumangsung ka anjeun karya simultaneous kalawan rékaman sarua? Atawa anjeun mess up jeung algoritma pikeun nelepon logika bisnis di sisi klien, contona? Sareng upami anjeun mikir ngeunaan éta? ..
sumber: www.habr.com