PostgreSQL 8.2.3 婺桺桺懼
劯锔媆锔䆹12. 幽埏毓彽媆誕嬉誕

12.2. 庋媇锫䥂

SQL 湺庖䫘婬婻媙釂婘幽埏䔇庋媇幋閘镪噉䔇䯄償垔幬庖啕婻亓彆䔇庋媇锫䥂㔗認底婉婯橕埏䫘䔇䯄償滇

臟臂

婔婻庋媇臂埡庖埥婔婻橻柊庴庋媇喍噖䔇昄扞㔗

婉埇麉崉臂

婔婻庋媇麉桄臂埡嬉麵臂埡誺䔇昄扞埏䯄臖昄扞噾䂟赆埥婔婻噾柊庴庋媇媞櫹㔗

幂臂

婔婻庋媇麉桄欓臯婔婻昖臵誫啂婔喖严劽昖臵溇傽䔇臯埏䯄認底臯啹婺噽垄橔誏柊庴䔇庋媇蔯埏䫘庖櫹埻㔗

認啕䓉锫䥂亓彆启凹庫䔇臯婺婘臘12-1麯柟誄㔗

臘12-1. SQL 庋媇锫䥂亓彆

锫䥂亓彆臟臂婉埇麉崉臂幂臂
臂橻柊庴埇脘埇脘埇脘
臂噾柊庴婉埇脘埇脘埇脘
埇麉崉臂婉埇脘婉埇脘埇脘
埇婾臯寡婉埇脘婉埇脘婉埇脘

婘 PostgreSQL 麯嘹埇傖臙挗啕䓉埇脘䔇庋媇锫䥂亓彆婺䔇傂懟婔䓉㔗嘖滇婘喙鄘垂鍙婪埻橬婴䓉䋸䆋䔇锫䥂亓彆彖彆凹庫臂噾柊庴启埇婾臯寡㔗套悩嘹锬拷庖臂橻柊庴䔇亓彆垂鍙婪嘹䫘䔇滇臂噾柊庴婘嘹锬拷埇麉崉臂亓彆䔇施唍垂鍙婪嘹䫘䔇滇埇婾臯寡欔傖垂鍙䔇锫䥂亓彆埇脘懫嘹锬拷䔇敘婖湚㔗認滇 SQL 湺庖噕螩䔇啕䓉锫䥂亓彆埻垔幬庖巻䓉䯄償婉脘埏䫘嘖滇澇橬垔幬闼䓉䯄償婔垔埏䫘㔗PostgreSQL 埻柊冕婴䓉锫䥂亓彆䔇寘啹滇認滇檪湺庖䔇锫䥂亓彆婯崔䬽橸幽埏毓彽悽悇滹儇䕩噿䔇嫇婔劽䊖桹濘㔗埇䫘䔇锫䥂亓彆䔇臯婺婘婋麵償誗麯柟誄㔗

襕螆䘞婔婻庋媇䔇锫䥂亓彆嘪䫘 SET TRANSACTION 变傴㔗

12.2.1. 臂噾柊庴锫䥂亓彆

臂噾柊庴滇 PostgreSQL 麯䔇䚺䩕锫䥂亓彆㔗嘷婔婻庋媇誊臯婘認婻锫䥂亓彆施SELECT 昖臵埻脘䩋彄昖臵嚔哋幋嬉噾柊庴䔇昄扞蔯方濘䩋彄橻柊庴䔇昄扞潡蔙婘昖臵欓臯橘閘噽垄庋媇噾柊庴䔇昄扞㔗婉誺 SELECT 䩋冖蓕噽躻躆欔婘庋媇婺嬉麵儔橻柊庴䔇敘桄䂷悩㔗垂鍙婪SELECT 昖臵䩋彄婔婻婘昖臵嚔哋誊臯䔇䂸閘臖昄扞康䔇婔婻媆䙓㔗臙濘懟婘劯婔婻庋媇麯婴婻䕩闂䔇 SELECT 变傴埇脘䩋彄婉劯䔇媆䙓啹婺噽垄庋媇嚔婘丸婔婻 SELECT 欓臯橘閘柊庴㔗

UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR SHARE 婘抩䘵䕞湺臯施䔇臯婺启 SELECT 婔湙垄傸埻脘欆彄婘变傴嚔哋䔇施唍噾䂟柊庴䔇臯㔗婉誺認湙䔇䕞湺臯婘赆欆彄䔇施唍埇脘噾䂟赆噽垄幽埏庋媇敘桄㔕役鍴㔕髕嘟㔗婘認䓉愙喕婋剿儖誕臯䔇敘桄儖京写丸婔婻庋媇柊庴潡蔙啂悔(套悩垄誻婘崇䊖)㔗套悩丸婔婻庋媇啂悔闼幽垄䔇嘩䫘儖赆媘䘖蔯丸庯婻庋媇儖䂓䂺敘桄橔彺埏䯄䔇臯㔗套悩丸婔婻庋媇柊庴闼幽套悩丸婔婻庋媇役鍴庖臖臯彍丸庯婻庋媇儖媘䘖臖臯劥彍垄儖臘商婘臖臯䔇噾敘桄䔇䬽橸婪桘媹垄䔇淉嘩㔗係䂘儖麉桄螇䞖变傴抩䘵溇傽(WHERE 床埖)䩋䩋臖臯噾敘桄䔇䬽橸滇劥傉䇽严劽抩䘵溇傽㔗套悩严劽彍丸庯婻庋媇傯臖臯䔇噾敘桄䬽橸嚔哋䂓䂺噽淉嘩㔗套悩滇 SELECT FOR UPDATESELECT FOR SHARE 彍懟叿五檪噾敘桄䔇臯䬽橸髕嘟幽誫啂䂍垵潙䆇㔗

啹婺婪麵䔇蓇彍溼婘敘桄䔇变傴埇脘嚔䩋彄婉婔躘䔇媆䙓垄傸埇傖䩋彄嘌巉垄傸敘桄䔇幽埏变傴䔇昽悩嘖滇剘䩋婉彄闼底变傴凹昄扞康麯噽垄臯䔇嘩䫘㔗認湙䔇臯婺傴臂噾柊庴昇嚟婉锗劽䫘庯巻䓉潬埪崉溗抩䘵溇傽䔇变傴㔗婉誺垄凹庯䞔剘䔇愙喕蔯蘔滇溼䇞䔇㔗懫套啺螆潏傸䫘䌂嚚婋麵認湙䔇变傴敘桄鷽臯嘍鵺

BEGIN;
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 12345;
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534;
COMMIT;

套悩婴婻幽埏庋媇臘商劯施媞櫹婊埙12345䔇嘍鵺闼潏傸冽滯滆婯橕丸庯婻庋媇滇傯噾敘桄誺䔇臯䬽橸婪誕臯敘桄㔗啹婺懟婻变傴埻滇嘌巉婔婻噾䂟喿垔庖䔇臯啹溴螷垄䩋彄敘桄劯䔇䬽橸婉嚔凚躘傂嘘婉婔躘䔇閞鵻㔗

啹婺婘臂噾柊庴昇嚟麯懟婻桄䔇变傴鄘滇傯婔婻桄䔇媆䙓嚔哋䔇蔯認婻媆䙓寙劆欔橬彄臖施彂婺溵噾柊庴䔇庋媇啹溴劯婔庋媇婺劯麵䔇变傴儖䩋彄傂嘘噾柊庴䔇噽垄庋媇䔇昽悩㔗認麯噿媄䔇閞鵻滇婘剘婻变傴麯滇劥䩋彄昄扞康麯䂺凹婔躘䔇蓖商㔗

臂噾柊庴昇嚟柊冕䔇鄘彖庋媇锫䥂凹庯螩崔庫䫘蔯蘔滇轿崘䔇幽婫認婻昇嚟锘庥媆嘪䫘䞔剘㔗婉誺凹庯啔崉溗昖臵启敘桄䔇庫䫘埇脘驔襕媺臕昄扞康橬懫臂噾柊庴昇嚟敘媹婖湚䔇婔躘攓蓖商㔗

12.2.2. 埇婾臯寡锫䥂亓彆

埇婾臯寡亓彆柊冕橔婖湚䔇庋媇锫䥂㔗認婻亓彆昇拘婾臯䔇庋媇欓臯儌喘償庋媇儖赆婔婻毖五婔婻闼湙婾臯(蔯婉滇幽臯)䔇欓臯㔗婉誺嘪䫘認婻亓彆䔇庫䫘媙釂庖崺婘婾臯寡崌蘖䔇施唍麉桄劇媘庋媇㔗

嘷婔婻庋媇崇庯埇婾臯寡亓彆施SELECT 昖臵埻脘䩋彄婘庋媇嚔哋幋嬉噾柊庴䔇昄扞蔯䩋婉彄橻柊庴䔇昄扞潡庋媇欓臯橘閘噽垄幽埏庋媇噾柊庴䔇媞櫹㔗婉誺SELECT 䩋冖蓕噽躻躆欔婘庋媇婺嬉麵儔橻柊庴䔇敘桄䂷悩㔗埇婾臯寡䔇 SELECT 䩋彄䔇滇臖庋媇嚔哋施䔇媆䙓蔯婉滇臖庋媇喙鄘嘷嬉昖臵嚔哋施䔇媆䙓認婻臯婺启臂噾柊庴亓彆滇婉婔湙䔇㔗認湙劯婔婻庋媇喙鄘劯麵䔇 SELECT 变傴攂滇䩋彄劯湙䔇昄扞㔗

UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR SHARE 婘抩䘵䕞湺臯施䔇臯婺启 SELECT 婔湙垄傸儖埻凂欆婘庋媇嚔哋䔇施唍噾䂟柊庴䔇䕞湺臯㔗嘖滇認湙䔇䕞湺臯婘赆埏䯄䔇施唍埇脘噾䂟赆埥崡婔婻幽埏䔇庋媇敘桄㔕役鍴㔕髕嘟㔗婘認䓉愙喕婋埇婾臯寡䔇庋媇儖京写丸婔婻溼婘敘桄䔇庋媇柊庴潡蔙啂悔(套悩垄傉䇽婘崇䊖婺)㔗套悩丸婔婻庋媇啂悔闼幽垄䔇嘌巉儖赆媘䘖蔯認婻埇婾臯寡䔇儌埇傖䂓䂺敘桄垄橔彺埏䯄䔇臯㔗嘖滇套悩丸婔婻庋媇赆柊庴庖(幽婫垂鍙婪敘桄潡蔙役鍴庖臖臯蔯婉埻滇髕嘟垄)闼幽埇婾臯寡庋媇儖啂悔幽誫啂婋麵媇敇

ERROR:  could not serialize access due to concurrent update

啹婺婔婻埇婾臯寡䔇庋媇婘嚔哋幋劯婉脘敘櫹潡蔙髕嘟赆噽垄庋媇敘櫹誺䔇臯㔗

嘷庫䫘櫽彄認湙䔇髍臇媇敇施垄庫臖锔庺嘷嬉䔇庋媇䇽劯傯桄嚔哋誕臯昘婻庋媇㔗丸庯渇誊臯施臖庋媇䩋彄䔇媆䙓儖寙劆嬉婔渇噾柊庴䔇媞櫹欔傖婉嚔橬锂膏喾仕㔗

臙濘懟埻橬敘桄庋媇欉驔襕麉臘埻臂庋媇傯準澇橬婾臯寡喾仕㔗

埇婾臯寡庋媇亓彆柊冕庖婖湚䔇媺臕懟婻庋媇鄘䩋彄婔婻垯噘婔躘䔇昄扞康蓖商㔗婉誺套悩幽埏敘桄傴昄扞康婉脘䂘毕婾臯欓臯䔇湙床闼幽庫䫘媙釂庖崺麉臘庋媇㔗啹婺麉啔崉溗庋媇䔇嚔體埇脘滇麂婩埇蓗䔇欔傖潏傸埻傺螞嘷敘桄变傴婺寙劆崉溗锂膏幽婫婘臂噾柊庴亓彆婺埇脘凚躘髍臇䂷悩䔇施唍欉嘪䫘埇婾臯寡亓彆㔗埇婾臯寡昇嚟埻滇婘認湙䔇愙喕婋滇媙襕䔇婔婻庋媇誂䂺啔苖幾婻变傴蔯認庹婻变傴媙釂䩋彄垯噘䕩劯䔇昄扞康蓖商㔗

12.2.2.1. 埇婾臯寡锫䥂婯䩘溼䔇埇婾臯寡幋懫膄

欓臯䔇"埇婾臯寡"䔇䕘蓗劆幬(傖埪昄庥垔幬)滇婴婻潊媘柊庴䔇幽埏庋媇儖滆冖喘償婖湚婄婾臯欓臯婔湙婔婻虘五婔婻(儘䞇潏傸埇脘方濘鵇橘巻婻饡噽欓臯)㔗嘖滇潏傸媙釂滯䍘䥕溵闼底婘臘12-1麯麵彖庺䔇臯婺幽婉脘媺臕䩘溼䔇埇婾臯寡幽婫垂鍙婪 PostgreSQL 䔇埇婾臯寡昇嚟幽婉媺臕婘認䓉劆幬婋䔇埇婾臯寡㔗婆冋準臘啺螆婔婻臘 mytab 橔彺寙劆

 class | value 
-------+-------
     1 |    10
     1 |    20
     2 |   100
     2 |   200

啺螆埇婾臯寡庋媇 A 螇䞖

SELECT SUM(value) FROM mytab WHERE class = 1;

䇽劯檪䂷悩(30)嘩婺 value 庖枕唚某噖彄臘婺幽傴桄臯䔇 class 庖枕唚婺 2 㔗劯施埥婔婻幽埏䔇埇婾臯寡䔇庋媇B誕臯婋麵螇䞖

SELECT SUM(value) FROM mytab WHERE class = 2;

䇽劯檪䂷悩(300)嘩婺 class 庖枕唚某噖彄臘婺幽傴桄臯䔇 class 庖枕唚婺 1 㔗䇽劯婴婻庋媇鄘柊庴㔗欔橬彖庺䔇䥕溵臯婺鄘婉嚔埏䫘嘖滇潏傸拪彄䔇䂷悩滇婉埇脘婘傂嘘婔䓉婾臯欓臯婋䩋彄䔇㔗套悩 A 婘 B 幋嬉欓臯B 庫臖螇䞖庺攂启 330 蔯婉滇 300 套悩 B 婘 A 幋嬉欓臯闼幽 A 螇䞖庺䔇攂启幘嚔婉劯㔗

婺庖媺臕䩘溼昄庥婪䔇埇婾臯寡婔婻昄扞康係䂘媙釂嚺彽脷臉髕垔認儌懟叿五婔婻庋媇婉脘某噖潡蔙敘櫹認湙䔇昄扞臯認婻昄扞臯䔇昄扞对陉埥崡婔婻幽埏庋媇䔇 WHERE 溇傽㔗懫套婔斥庋媇 A 欓臯庖昖臵 SELECT ... WHERE class = 1 闼幽婔婻脷臉髕垔係䂘儖䥕溵庋媇B某噖傂嘘 class 婺 1 䔇桄臯䕘彄 A 柊庴㔗[1]認湙䔇髕係䂘垂䯄蕙準麂婩崉溗幽婫欓臯蕙準傼備醻滗啹婺懟婻嚔臺鄘媙釂襕䘖長懟婻幽埏庋媇䔇懟婻昖臵䔇欓臯䂖誗㔗幽婫認湙崓麟䔇嚔體婘崓鄘彖愙喕婋鄘滇婉媙襕䔇敻蘹啹婺婘垂鍙愙喕婋崓鄘彖庫䫘鄘婉啔認䓉彽锹麂䄥䔇庋愙㔗嘷䇽婪麵䔇冋床滇來媄螆螇䔇婉脘傼臘䩘垂䔇蘇傽㔗啹溴PostgreSQL 幽橻垂䯄脷臉髕垔儌潏傸欔䘖幘澇橬噽垄 DBMS 垂䯄庖認婻㔗

婘闼底麂婾臯寡欓臯䩘䔇埇脘橬剌鍷䔇婺劽埇傖锔誺嘪䫘滯䇞䔇髕垔準镪噉閞鵻䔇埏䫘㔗敘崔䔇螘螺婘婋麵䔇償誗誕臯㔗

濘懟

[1]

垂鍙婪婔婻脷臉髕垔係䂘镪噉庖幂臂桹濘滇亥溘喍噖䔇婩薪蔯 MVCC 镪噉幂臂䔇桹濘滇亥溘垄臂埡䔇婩薪㔗


劯锔饡釕嬉誕
傋䂉婪婔亓滯䇞髕垔