这是使用 libpq.so 的伪代码;但它并不像我想的那样。
transaction begin
re1 = [select ics_time from table1 where c1=c11, c2=c22, c3=c33, c4=c44 for update];
if(re1 satisfies the condition)
{
re2 = [select id where c1=c11, c2=c22, c3=c33, c4=c44 for update];
delete from table1 where id = re2;
delete from table2 where id = re2;
delete from table3 where id = re3;
insert a new record into table1,table2,table3 with the c1,c2,c3,c4 as primary keys;
]
commit or rollback
注意c1,c2,c3,c4在数据库中都设置为主键,所以数据库中只有一行有这些键。
让我感到困惑的是:
- 有两个“选择更新”将锁定同一行。在这段代码中,第二条 SQL 语句是否等待被第一条语句阻塞的排他锁?但是,实际情况是它并没有发生。
- 发生了一些出乎我意料的事情。在日志中,我看到大量重复插入错误。在我看来,“选择更新”用唯一的键锁定行,两个过程连续进行。插入操作在删除之后进行。这些重复插入是如何发生的?“select for update”不是为该行添加了一个排他锁,这会阻止所有其他想要锁定同一行的进程吗?