13.4. ÐÑовеÑки ÑелоÑÑноÑÑи даннÑÑ Ð½Ð° ÑÑовне пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ #
ÐÑполÑзÑÑ ÑÑанзакÑии Read Committed, оÑÐµÐ½Ñ Ñложно обеÑпеÑиÑÑ ÑелоÑÑноÑÑÑ Ð´Ð°Ð½Ð½ÑÑ Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð±Ð¸Ð·Ð½ÐµÑ-логики, Ñак как пÑедÑÑавление даннÑÑ ÑмеÑаеÑÑÑ Ñ ÐºÐ°Ð¶Ð´Ñм опеÑаÑоÑом и даже один опеÑаÑÐ¾Ñ Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ огÑаниÑиваÑÑÑÑ Ñвоим Ñнимком ÑоÑÑоÑÐ½Ð¸Ñ Ð² ÑлÑÑае конÑликÑа запиÑи.
ХоÑÑ ÑÑанзакÑÐ¸Ñ Repeatable Read полÑÑÐ°ÐµÑ ÑÑабилÑное пÑедÑÑавление даннÑÑ Ð² пÑоÑеÑÑе вÑполнениÑ, Ñ Ð¸ÑполÑзованием Ñнимков MVCC Ð´Ð»Ñ Ð¿ÑовеÑки ÑелоÑÑноÑÑи даннÑÑ Ð²ÑÑ Ð¶Ðµ ÑвÑÐ·Ð°Ð½Ñ Ñонкие моменÑÑ, вклÑÑÐ°Ñ Ñак назÑваемÑе конÑликÑÑ ÑÑениÑ/запиÑи. ÐÑли одна ÑÑанзакÑÐ¸Ñ Ð·Ð°Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ Ð´Ð°Ð½Ð½Ñе, а дÑÑÐ³Ð°Ñ Ð² ÑÑо же вÑÐµÐ¼Ñ Ð¿ÑÑаеÑÑÑ Ð¸Ñ Ð¿ÑоÑиÑаÑÑ (до или поÑле запиÑи), она не Ð¼Ð¾Ð¶ÐµÑ ÑвидеÑÑ ÑезÑлÑÑÐ°Ñ ÑабоÑÑ Ð¿ÐµÑвой. Ð Ñаком ÑлÑÑае ÑоздаÑÑÑÑ Ð²Ð¿ÐµÑаÑление, ÑÑо ÑиÑаÑÑÐ°Ñ ÑÑанзакÑÐ¸Ñ Ð²ÑполнÑеÑÑÑ Ð¿ÐµÑвой вне завиÑимоÑÑи Ð¾Ñ Ñого, ÐºÐ°ÐºÐ°Ñ Ð¸Ð· Ð½Ð¸Ñ Ð±Ñла наÑаÑа или заÑикÑиÑована ÑанÑÑе. ÐÑли ÑÑим вÑÑ Ð¸ огÑаниÑиваеÑÑÑ, Ð½ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ Ð¿Ñоблем, но еÑли ÑиÑаÑÑÐ°Ñ ÑÑанзакÑÐ¸Ñ Ñакже пиÑÐµÑ Ð´Ð°Ð½Ð½Ñе, коÑоÑÑе ÑиÑÐ°ÐµÑ Ð¿Ð°ÑаллелÑÐ½Ð°Ñ ÑÑанзакÑиÑ, полÑÑаеÑÑÑ, ÑÑо ÑепеÑÑ ÑÑа ÑÑанзакÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð¸ÑполнÑÑÑÑÑ, как бÑдÑо она запÑÑена пеÑед дÑÑгими вÑÑеÑпомÑнÑÑÑми. ÐÑли же ÑÑанзакÑиÑ, коÑоÑÐ°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° иÑполнÑÑÑÑÑ ÐºÐ°Ðº поÑледнÑÑ, на Ñамом деле заÑикÑиÑована пеÑвой, в гÑаÑе ÑпоÑÑдоÑеннÑÑ ÑÑанзакÑий легко Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ñикл. Ркогда он возникаеÑ, пÑовеÑки ÑелоÑÑноÑÑи не бÑдÑÑ ÑабоÑаÑÑ Ð¿ÑавилÑно без дополниÑелÑнÑÑ Ð¼ÐµÑ.
Ðак бÑло Ñказано в ÐодÑазделе 13.2.3, ÑеÑиализÑемÑе ÑÑанзакÑии пÑедÑÑавлÑÑÑ Ñобой Ñе же ÑÑанзакÑии Repeatable Read, но дополненнÑе неблокиÑÑÑÑим Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ð¾Ð¼ оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾Ð¿Ð°ÑнÑÑ ÑÑловий конÑликÑов ÑÑениÑ/запиÑи. Ðогда вÑÑвлÑеÑÑÑ ÑÑловие, пÑиводÑÑее к ÑÐ¸ÐºÐ»Ñ Ð² поÑÑдке ÑÑанзакÑий, одна из ÑÑÐ¸Ñ ÑÑанзакÑий оÑкаÑÑваеÑÑÑ Ð¸ ÑÑÐ¾Ñ Ñикл Ñаким обÑазом ÑазÑÑваеÑÑÑ.
13.4.1. ÐбеÑпеÑение ÑоглаÑованноÑÑи в ÑеÑиализÑемÑÑ ÑÑанзакÑиÑÑ #
ÐÑли Ð´Ð»Ñ Ð²ÑÐµÑ Ð¾Ð¿ÐµÑаÑий ÑÑÐµÐ½Ð¸Ñ Ð¸ запиÑи, нÑждаÑÑÐ¸Ñ ÑÑ Ð² ÑоглаÑованном пÑедÑÑавлении даннÑÑ , иÑполÑзÑÑÑÑÑ ÑÑанзакÑии ÑÑÐ¾Ð²Ð½Ñ Ð¸Ð·Ð¾Ð»ÑÑии Serializable, ÑÑо обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ ÑоглаÑованноÑÑÑ Ð±ÐµÐ· дополниÑелÑнÑÑ ÑÑилий. ÐÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð· дÑÑÐ³Ð¸Ñ Ð¾ÐºÑÑжений, пÑименÑÑÑие ÑеÑиализÑемÑе ÑÑанзакÑии Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÑелоÑÑноÑÑи, в Postgres Pro в ÑÑом ÑмÑÑле бÑдÑÑ Â«Ð¿ÑоÑÑо ÑабоÑаÑÑ».
ÐÑименение ÑÑого подÑ
ода избавлÑÐµÑ Ð¿ÑогÑаммиÑÑов пÑиложений Ð¾Ñ Ð»Ð¸ÑниÑ
ÑложноÑÑей, еÑли пÑиложение иÑполÑзÑÐµÑ Ð¸Ð½ÑÑаÑÑÑÑкÑÑÑÑ, коÑоÑÐ°Ñ Ð°Ð²ÑомаÑиÑеÑки повÑоÑÑÐµÑ ÑÑанзакÑии в ÑлÑÑае оÑкаÑа из-за Ñбоев ÑеÑиализаÑии. Ðозможно, serializable ÑÑÐ¾Ð¸Ñ Ð´Ð°Ð¶Ðµ ÑÑÑановиÑÑ Ð² каÑеÑÑве ÑÑÐ¾Ð²Ð½Ñ Ð¸Ð·Ð¾Ð»ÑÑии по ÑмолÑÐ°Ð½Ð¸Ñ (default_transaction_isolation). Также Ð¸Ð¼ÐµÐµÑ ÑмÑÑл пÑинÑÑÑ Ð¼ÐµÑÑ Ð´Ð»Ñ Ð¿ÑедоÑвÑаÑÐµÐ½Ð¸Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´ÑÑгиÑ
ÑÑовней изолÑÑии, непÑеднамеÑенного или Ñ ÑелÑÑ Ð¾Ð±Ð¾Ð¹Ñи пÑовеÑки ÑелоÑÑноÑÑи, напÑÐ¸Ð¼ÐµÑ Ð¿ÑовеÑÑÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ Ð¸Ð·Ð¾Ð»ÑÑии в ÑÑиггеÑаÑ
.
РекомендаÑии по ÑвелиÑÐµÐ½Ð¸Ñ Ð±ÑÑÑÑодейÑÑÐ²Ð¸Ñ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð² ÐодÑазделе 13.2.3.
ÐÑедÑпÑеждение: ÑеÑиализÑемÑе ÑÑанзакÑии и ÑепликаÑÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÐаÑиÑа ÑелоÑÑноÑÑи Ñ Ð¿Ñименением ÑеÑиализÑемÑÑ ÑÑанзакÑий пока еÑÑ Ð½Ðµ поддеÑживаеÑÑÑ Ð² Ñежиме гоÑÑÑего ÑезеÑва (Раздел 25.4) или логиÑеÑÐºÐ¸Ñ Ñеплик. ÐоÑÑÐ¾Ð¼Ñ Ñам, где пÑименÑеÑÑÑ Ð³Ð¾ÑÑÑий ÑезеÑв или логиÑеÑÐºÐ°Ñ ÑепликаÑиÑ, ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ Repeatable Read и ÑвнÑе блокиÑовки на главном ÑеÑвеÑе.
13.4.2. ÐÑименение ÑвнÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовок Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÑоглаÑованноÑÑи #
Ðогда Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ Ð½ÐµÑеÑиализÑемÑе опеÑаÑии запиÑи, Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÑелоÑÑноÑÑи ÑÑÑок и заÑиÑÑ Ð¾Ñ Ð¾Ð´Ð½Ð¾Ð²ÑеменнÑÑ
изменений, ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ SELECT FOR UPDATE, SELECT FOR SHARE или ÑооÑвеÑÑÑвÑÑÑий опеÑаÑÐ¾Ñ LOCK TABLE. (SELECT FOR UPDATE и SELECT FOR SHARE заÑиÑаÑÑ Ð¾Ñ Ð¿Ð°ÑаллелÑнÑÑ
изменений ÑолÑко возвÑаÑаемÑе ÑÑÑоки, Ñогда как LOCK TABLE блокиÑÑÐµÑ Ð²ÑÑ ÑаблиÑÑ.) ÐÑо ÑледÑÐµÑ ÑÑиÑÑваÑÑ, пеÑеноÑÑ Ð² Postgres Pro пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð· дÑÑгиÑ
СУÐÐ.
ÐигÑиÑÑÑ Ð² Postgres Pro из дÑÑгиÑ
СУÐÐ Ñакже ÑледÑÐµÑ ÑÑиÑÑваÑÑ, ÑÑо команда SELECT FOR UPDATE Ñама по Ñебе не гаÑанÑиÑÑеÑ, ÑÑо паÑаллелÑÐ½Ð°Ñ ÑÑанзакÑÐ¸Ñ Ð½Ðµ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ не ÑÐ´Ð°Ð»Ð¸Ñ Ð²ÑбÑаннÑÑ ÑÑÑокÑ. ÐÐ»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ñакой гаÑанÑии в Postgres Pro нÑжно именно измениÑÑ ÑÑÑ ÑÑÑокÑ, даже еÑли никакие знаÑÐµÐ½Ð¸Ñ Ð² ней менÑÑÑ Ð½Ðµ ÑÑебÑеÑÑÑ. SELECT FOR UPDATE вÑеменно блокиÑÑÐµÑ Ð´ÑÑгие ÑÑанзакÑии, не Ð´Ð°Ð²Ð°Ñ Ð¸Ð¼ полÑÑиÑÑ ÑÑ Ð¶Ðµ блокиÑÐ¾Ð²ÐºÑ Ð¸Ð»Ð¸ вÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ UPDATE или DELETE, коÑоÑÑе Ð±Ñ Ð¿Ð¾Ð²Ð»Ð¸Ñли на заблокиÑованнÑÑ ÑÑÑокÑ, но как ÑолÑко ÑÑанзакÑиÑ, владеÑÑÐ°Ñ ÑÑой блокиÑовкой, ÑикÑиÑÑеÑÑÑ Ð¸Ð»Ð¸ оÑкаÑÑваеÑÑÑ, заблокиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ ÑÑанзакÑÐ¸Ñ ÑÐ¼Ð¾Ð¶ÐµÑ Ð²ÑполниÑÑ ÐºÐ¾Ð½ÑликÑÑÑÑÑÑ Ð¾Ð¿ÐµÑаÑиÑ, еÑли ÑолÑко Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑÑÑоки дейÑÑвиÑелÑно не бÑл вÑполнен UPDATE, пока ÑÑанзакÑÐ¸Ñ Ð²Ð»Ð°Ð´ÐµÐ»Ð° блокиÑовкой.
РеализаÑÐ¸Ñ Ð³Ð»Ð¾Ð±Ð°Ð»Ñной ÑелоÑÑноÑÑи Ñ Ð¸ÑполÑзованием неÑеÑиализÑемÑÑ
ÑÑанзакÑий MVCC ÑÑебÑÐµÑ Ð±Ð¾Ð»ÐµÐµ вдÑмÑивого подÑ
ода. ÐапÑимеÑ, банковÑÐºÐ¾Ð¼Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð¿ÑовеÑиÑÑ, ÑавнÑеÑÑÑ Ð»Ð¸ ÑÑмма вÑеÑ
ÑаÑÑ
одов в одной ÑаблиÑе ÑÑмме пÑиÑ
одов в дÑÑгой, пÑи Ñом, ÑÑо обе ÑаблиÑÑ Ð°ÐºÑивно изменÑÑÑÑÑ. ÐÑоÑÑо ÑÑавниваÑÑ ÑезÑлÑÑаÑÑ Ð´Ð²ÑÑ
ÑÑпеÑнÑÑ
поÑледоваÑелÑнÑÑ
команд SELECT sum(...) в Ñежиме Read Committed нелÑзÑ, Ñак как вÑоÑÐ°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ñ
ваÑиÑÑ ÑезÑлÑÑаÑÑ ÑÑанзакÑий, пÑопÑÑеннÑÑ
пеÑвой. ÐодÑÑиÑÑÐ²Ð°Ñ ÑÑÐ¼Ð¼Ñ Ð² одной ÑÑанзакÑии Repeatable Read, можно полÑÑиÑÑ ÑоÑнÑÑ ÐºÐ°ÑÑÐ¸Ð½Ñ ÑолÑко Ð´Ð»Ñ ÑÑанзакÑий, коÑоÑÑе бÑли заÑикÑиÑÐ¾Ð²Ð°Ð½Ñ Ð´Ð¾ наÑала данной, но пÑи ÑÑом Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð·Ð°ÐºÐ¾Ð½Ð½Ñй вопÑÐ¾Ñ â бÑÐ´ÐµÑ Ð»Ð¸ ÑÑÐ¾Ñ ÑезÑлÑÑÐ°Ñ Ð°ÐºÑÑален Ñогда, когда он бÑÐ´ÐµÑ Ð²Ñдан. ÐÑли ÑÑанзакÑÐ¸Ñ Repeatable Read Ñама вноÑÐ¸Ñ ÐºÐ°ÐºÐ¸Ðµ-Ñо изменениÑ, пÑежде Ñем пÑовеÑÑÑÑ ÑавенÑÑво ÑÑмм, полезноÑÑÑ ÑÑой пÑовеÑки ÑÑановиÑÑÑ ÐµÑÑ Ð±Ð¾Ð»ÐµÐµ ÑомниÑелÑной, Ñак как пÑи пÑовеÑке бÑдÑÑ ÑÑиÑÑваÑÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе, но не вÑе изменениÑ, пÑоизоÑедÑие поÑле наÑала ÑÑанзакÑии. Ð ÑакиÑ
ÑлÑÑаÑÑ
пÑедÑÑмоÑÑиÑелÑнÑй ÑазÑабоÑÑик Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸ÑоваÑÑ Ð²Ñе ÑаблиÑÑ, задейÑÑвованнÑе в пÑовеÑке, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ°ÑÑÐ¸Ð½Ñ Ð´ÐµÐ¹ÑÑвиÑелÑноÑÑи, не вÑзÑваÑÑÑÑ Ñомнений. ÐÐ»Ñ ÑÑого пÑименÑеÑÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка SHARE (или более ÑÑÑогаÑ), коÑоÑÐ°Ñ Ð³Ð°ÑанÑиÑÑеÑ, ÑÑо в заблокиÑованной ÑаблиÑе не бÑÐ´ÐµÑ Ð½ÐµÐ·Ð°ÑикÑиÑованнÑÑ
изменений, за иÑклÑÑением ÑеÑ
, ÑÑо внеÑла ÑекÑÑÐ°Ñ ÑÑанзакÑиÑ.
Также замеÑÑÑе, ÑÑо, пÑименÑÑ ÑвнÑе блокиÑовки Ð´Ð»Ñ Ð¿ÑедоÑвÑаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑаллелÑнÑÑ
опеÑаÑий запиÑи, ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ Ð»Ð¸Ð±Ð¾ Ñежим Read Committed, либо в Ñежиме Repeatable Read обÑзаÑелÑно полÑÑаÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки пÑежде, Ñем вÑполнÑÑÑ Ð·Ð°Ð¿ÑоÑÑ. ÐлокиÑовка, полÑÑÐ°ÐµÐ¼Ð°Ñ ÑÑанзакÑией Repeatable Read, гаÑанÑиÑÑеÑ, ÑÑо Ð½Ð¸ÐºÐ°ÐºÐ°Ñ Ð´ÑÑÐ³Ð°Ñ ÑÑанзакÑиÑ, изменÑÑÑÐ°Ñ ÑаблиÑÑ, не вÑполнÑеÑÑÑ, но еÑли Ñнимок ÑоÑÑоÑниÑ, полÑÑеннÑй ÑÑанзакÑией, пÑедÑеÑÑвÑÐµÑ Ð±Ð»Ð¾ÐºÐ¸Ñовке, он Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ вклÑÑаÑÑ Ð½Ð° даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ñже заÑикÑиÑованнÑе изменениÑ. Снимок ÑоÑÑоÑÐ½Ð¸Ñ Ð² ÑÑанзакÑии Repeatable Read ÑоздаÑÑÑÑ ÑакÑиÑеÑки на Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð½Ð°Ñала пеÑвой ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð²ÑбоÑки или Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
(SELECT, INSERT, UPDATE, DELETE или MERGE), Ñак ÑÑо полÑÑиÑÑ ÑвнÑе блокиÑовки можно до Ñого, как он бÑÐ´ÐµÑ ÑÑоÑмиÑован.