【问题标题】:INSERT in one table but it locks another table [closed]在一个表中插入,但它锁定了另一个表[关闭]
【发布时间】:2014-01-27 22:00:23
【问题描述】:

我现在遇到了 SQL Server 表锁定问题。我正在使用 C# 进行开发。

我的查询在 1 个事务下运行。

我将其命名为最简单的识别方式。 “设置交易”

setTransaction 仅适用于“INSERT / UPDATE / DELETE”。

  • 如果我想做SELECT。我将使用SqlDataAdapter
  • 如果我想做INSERT/UPDATEDELETE,是时候使用setTransaction了。

这里是每个的表结构...

[LOG](
    [log_id] [int] IDENTITY(1,1) NOT NULL,
    [subject] [text] NOT NULL,
    [query] [text] NOT NULL,
    [log_datetime] [datetime] NOT NULL,
    [user_id] [int] NOT NULL,
    [emp_id] [int] NULL,
    [old_value] [text] NULL
)

[RESERVATION_DETAIL](
    [**reservation_detail_id**] [int] IDENTITY(1,1) NOT NULL,
    [reservation_id] [int] NOT NULL,
    [spa_program_id] [int] NULL,
    [price] [int] NULL,
    [oil] [int] NULL
)

[RESERVATION_THERAPIST](
    [reservation_therapist_id] [int] IDENTITY(1,1) NOT NULL,
    [**reservation_detail_id**] [int] NOT NULL,
    [therapist_id] [int] NOT NULL,
    [hours] [int] NULL,
    [mins] [int] NULL
)

[LOG] 正在独立工作。 [RESERVATION_DETAIL] 通过 reservation_detail_id 连接到 [RESERVATION_THERAPIST]

问题是……

  1. 开始交易。 我想从“RESERVATION_DETAIL”中删除一条reservation_detail_id = 25
  2. 的记录
  3. 我从“RESERVATION_DETAIL”中选择一条reservation_detail_id = 25的记录

    SELECT * FROM RESERVATION_DETAIL WHERE RESERVATION_DETAIL_ID = 25

  4. 我将来自 2 的数据插入到表“LOG”中。

    INSERT INTO LOG(主题、查询、log_datetime、user_id、emp_id、old_value)值( '从 RES_DETAIL[RES_DETAIL_ID:25] 中删除临时保留区', '从 RESERVATION_DETAIL 中删除 RESERVATION_DETAIL_ID = 25', CURRENT_TIMESTAMP, 1、 NULL, 'reservation_detail_id:25|reservation_id:25|spa_program_id:-1|price:|oil:' )

  5. 现在我从“RESERVATION_DETAIL”中删除其中 reservation_detail_id = 25

    然后我想从“RESERVATION_THERAPIST”中删除一条reservation_detail_id = 25的记录

    从 RESERVATION_DETAIL 中删除,其中 RESERVATION_DETAIL_ID = 25

  6. 我从“RESERVATION_THERAPIST”中选择了一条reservation_detail_id = 25

    的记录

    SELECT * FROM RESERVATION_THERAPIST WHERE RESERVATION_DETAIL_ID = 25

  7. 我将 5 中的数据插入到表“LOG”中。

  8. 最后,我将从“RESERVATION_THERAPIST”中删除其中 reservation_detaiil_id = 25

因此运行了上述步骤。 第 5 步(关于表“RESERVATION_THERAPIST”)现在等待第 3 步(关于表“LOG”)完成,但它从未完成。

我不明白为什么我插入到表 LOG 但它把锁放在表 B 上!?或者这不是锁!?

上述步骤之前的查询插入LOG没有任何问题。


现在我可以解决我的问题了。

查询和步骤已经OK了。

但我忘记了“RESERVATION_DETAIL”表有一个触发器,该触发器将在 DELETE 查询提交后立即运行。

所以触发器会自动删除“RESERVATION_THERAPIST”中的一条记录,这一步在事务下。

所以“RESERVATION_THERAPIST”在“DELETE FROM RESERVATION_DETAIL”之后但在我可以“SELECT * FROM RESERVATION_THERAPIST”之前被锁定

【问题讨论】:

  • 我们为什么要大喊大叫?
  • 你在你的帖子中给出表结构和确切的sql怎么样?
  • 它们难读吗?
  • @ChatawatL。是的。请用结构编辑问题
  • 请删除上面三个试图显示表结构的cmets。实际上,几乎所有的 cmets。

标签: c# sql sql-server transactions deadlock


【解决方案1】:

在删除完成之前,有几件事可能导致表被锁定:

  1. 您正在尝试从表中直接删除
  2. 您已为已锁定表的父表启用级联删除。
  3. 您在另一个表上有一个触发器,您正在从中执行操作,该触发器也会从该表中删除。
  4. 您正在尝试乱序删除表(始终先删除子表,然后删除父表。从父表中删除时,它会检查是否存在子记录。这当然比直接删除要长删除,如果子数据存在则将导致回滚,这需要更长的时间。
  5. 同时运行的两个进程之间出现死锁。

【讨论】:

  • 我在您发布此问题的同时找到了我的答案。但我的声誉不到 10,所以我无法回答自己的问题。然后我接受你的:)
【解决方案2】:

你获得了 B 的锁,因为你从 B 中删除了。

【讨论】:

  • 感谢您的回复。我编辑了我的问题并将真实的表名放入其中。 :)
猜你喜欢
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 2016-06-11
相关资源
最近更新 更多