1

给定两个表:

  • Company[ id, name, balance]
  • Employee[ id, name, company_id]

我想删除一家公司及其依赖项,但我不能原子地这样做,因为在我的实际项目中,一家公司有多个级别的依赖项,这太复杂而无法压缩到单个 SQL 语句中。此外,查看https://stackoverflow.com/a/5598275/14731我不确定单个 SQL 语句是否是原子的。

相反,我这样做:

  1. SELECT ... FOR UPDATE与公司相关的所有员工(锁定他们以防止在交易中进行修改)
  2. 一个一个地删除每个员工
  3. 删除母公司。

有一个问题:如何防止在第 1 步和第 2 步之间插入引用公司的新记录?根据https://stackoverflow.com/a/3602125/14731 SELECT ... FOR UPDATE不阻止插入。理想情况下,我想在 Company 上加一把锁,而不是每一种可能指向它的依赖项都加一把锁。

更新:我有一个想法,但我不确定它是否有意义。

如果有人想插入指向公司的新记录,他们可能需要查找它以确保它存在。如果我SELECT ... FOR UPDATE在第 1 步之前就连上了,就应该阻止他们的读取,从而延迟随后的插入。我有两个问题:

  1. SELECT ... FOR UPDATE阻止正常SELECT查询吗?如果没有,我必须确保SELECT ... FOR UPDATE在查找公司时始终使用插入线程。
  2. 这种方法行得通吗?
4

1 回答 1

0

这是一种可能的解决方案:

  1. 插入新关联的线程应该在公司上建立一个读锁(使用REPEATABLE_READ隔离或SELECT ... FOR SHARE
  2. 删除 Company 的线程应使用 写锁定行SELECT ... FOR UPDATE
  3. 写锁将等待所有未完成的读锁被释放,并在DELETE操作完成之前阻止建立新的读锁。
于 2013-05-14T03:01:45.267 回答