c – 由2个SQL连接创建的死锁,每个连接使用事务,不同的表,两个表之间的外键约束

环境

我正在使用SQL Native Client 9.0与SQL Server 2000数据库进行通信的C应用程序.

脚本

> DBMS打开了2个连接
>每个连接都设置为使用事务
> Connection1上的查询与TableA一起使用
> Connection2上的查询与TableB一起使用
> TableB在TableA中的key_id字段上具有外键约束

我构造了执行以下操作的函数:

begin a transaction on Connection1 & Connection2
prepare a query in TableA on Connection1
prepare a query on TableB on Connection2

begin loop over some_data
   (1) insert into key_id on TableA

   begin loop over some_other_data
      (2) insert into TableB using same key_id as in Table A
   end loop
end loop

commit on Connection1
commit on Connection2

我遇到的是查询(1)成功执行但是只要为查询(2)调用SQLExecute,调试器就会永远不会出现.

问题

我是否正确地将正在发生的事情诊断为死锁问题?

我收集到了,因为Connection1正在TableA中创建一个键而不提交它,然后Connection2尝试向TableB添加信息,由于外键约束,必须在TableA中存在键.正因为如此,SQLExecute查询阻塞,等待TableA上的事务完成,直到TableB完成其写入才能完成,这要归功于编写代码的方式.

补充说明

我可以而且已经围绕这个问题编码,但我想确保我对这个问题的理解是正确的.

最佳答案
TableB对TableA的外键约束必须检查以确认密钥的存在.然后它将接受或拒绝TableB记录.

由于包含密钥的TableA记录(在不同的连接上)尚未提交,因此外键约束必须等待 – 在提交或回滚TableA记录之前,插入不会返回.

因为第一个连接上的提交等待TableB插入返回…您有死锁.

换句话说,你是对的.

转载注明原文:c – 由2个SQL连接创建的死锁,每个连接使用事务,不同的表,两个表之间的外键约束 - 代码日志