gpt4 book ai didi

c# - 事务和锁

转载 作者:太空宇宙 更新时间:2023-11-03 21:55:11 24 4
gpt4 key购买 nike

我目前正在处理事务并且感到困惑。这些事务是在数据访问层创建的,而不是在数据库的存储过程中创建的 (SQL Server 2008)。我了解为事务设置的隔离级别的正常工作。我无法理解在以下情况下会发生什么。

  1. 发起交易
  2. 选择 ID=1 的员工。
  3. 更新 ID=1 的员工。
  4. promise

有多个线程在做同样的事情但 ID 不同。但是可能会出现这样的情况,即在两个线程中查找相同的 ID。让我们称它们为线程 A 和 B。以上步骤针对这两个线程按以下方式进行。隔离级别设置为可重复读取。

A1。发起交易A2。选择 ID=1 的员工。B1.发起交易B2.选择 ID=1 的员工。A3.更新 ID=1 的员工。A4.犯罪B3.更新 ID=1 的员工。B4.提交

我真正想从事务中实现的是,当线程 A 选择特定记录时,线程 B 甚至不能选择该记录。对于这种情况,我不知道通过使用事务和锁来思考是否在正确的轨道上。

等待回复:)

最佳答案

您应该使用 UPDLOCK 表提示来防止死锁,例如,

select * from employee with (updlock) where id = @id
update employee set name = @name where id = @id

没有这个你可能会遇到死锁,因为默认情况下选择采用共享读锁:

  1. 事务 A 执行选择(共享读锁)。
  2. 事务 B 执行选择(共享读锁,可能在某些与事务 A 相同的记录,例如,如果页面锁定被占用)。
  3. 事务 A 现在执行更新,这需要独占写入lock(锁升级),但要等待事务B释放它的共享读锁。
  4. 事务 B 现在也想进行更新,但必须等待事务 A 释放其共享读锁。

因此事务 A 和 B 现在正在等待对方 - 经典锁升级死锁。 UPDLOCK 表提示避免了这种情况,因为它强制选择采用排他锁:

  1. 事务 A 进行选择(独占更新锁)。
  2. 事务 B 想要进行选择,但必须先等待事务 A 释放其锁。
  3. 事务 A 现在执行更新并提交,释放 select 获取的更新锁。
  4. 事务 B 现在可以进行选择。

编辑:您可以将 UPDLOCK 与 ROWLOCK 结合使用以请求行级锁,例如“with (updlock, rowlock)”。你可以问,但你不一定总能得到 - 见http://msdn.microsoft.com/en-us/library/ms187373(v=sql.100).aspx .此外,行锁可能比页锁更昂贵,因为如果使用行锁,SQL Server 可能需要跟踪更多的锁。所以我会让 SQL Server 自己选择锁的范围,它通常做得很好;在这种情况下,它不应该使用表锁。仅在没有行锁的情况下出现问题时才显式使用行锁。

另请注意,行锁本身不会阻止两个事务选择相同记录(行)然后尝试更新它的死锁 - 因此您始终需要一个更新锁。

关于c# - 事务和锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12616509/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com