我在pg_log中收到以下死锁错误:
2016-01-15 09:52:48.648 EST,"name","name",11694,"ip:40273",56988e35.2dae,1,"UPDATE",2016-01-15 01:14:13 EST,10/3886,49775,ERROR,40P01,
"deadlock detected",
"Process 11694 waits for ShareLock on transaction 49774; blocked by process 11685.
Process 11685 waits for ShareLock on transaction 49775; blocked by process 11694.
Process 11694: update bb_batter_season_stat set a_field=a_field+$1, ab_int=ab_int+$2, abvsl=abvsl+$3, abvsr=abvsr+$4, bbvsl=bbvsl+$5, bbvsr=bbvsr+$6, cs=cs+$7,
cs_field=cs_field+$8, ... where bb_players_id=$53
Process 11685: update bb_batter_season_stat set a_field=a_field+$1, ab_int=ab_int+$2, abvsl=abvsl+$3, abvsr=abvsr+$4, bbvsl=bbvsl+$5, bbvsr=bbvsr+$6, cs=cs+$7,
cs_field=cs_field+$8, ... where bb_players_id=$53","See server log for query details.",,,,
"update bb_batter_season_stat set a_field=a_field+$1, ab_int=ab_int+$2, abvsl=abvsl+$3,
abvsr=abvsr+$4, bbvsl=bbvsl+$5, bbvsr=bbvsr+$6, cs=cs+$7, cs_field=cs_field+$8, ... where bb_players_id=$53",,,""
我无法理解为什么会这样。发生两个运行相同查询和死锁的进程。
表架构是:
CREATE TABLE bb_batter_season_stat (
id SERIAL NOT NULL ,
bb_players_id INTEGER NOT NULL ,
G SMALLINT ,
ABvsL SMALLINT ,
ABvsR SMALLINT ,
RvsL SMALLINT ,
RvsR SMALLINT ,
HvsL SMALLINT ,
HvsR SMALLINT ,
d2BvsL SMALLINT ,
d2BvsR SMALLINT ,
...
PRIMARY KEY(id) ,
FOREIGN KEY(bb_players_id) REFERENCES bb_players(id) );
CREATE INDEX bb_batter_season_stat_FKIndex1 ON bb_batter_season_stat (bb_players_id);
答案 0 :(得分:0)
我认为bb_batter_season_stat
中至少有2条记录具有相同的bb_players_id
。
为避免这种情况,您应该按主键的顺序强制锁定记录。例如,使用select for update
:
with ids as (
select id
from bb_batter_season_stat
where bb_players_id=?
order by id
for update
)
update bb_batter_season_stat
set a_field=a_field+$1, ab_int=ab_int+$2, …
where id in (select id from ids);