交易期间如何锁定数据
How is data locked during a transaction
我开始使用 SQL 服务器数据库,但我很难理解 Transaction Isolation Levels
以及它们如何锁定数据。
我正在尝试完成以下简单任务:
- 在 SQL 存储过程中接受一对整数 [ID, counter]
- 判断ID是否存在于某个table:
SELCT COUNT(*) FROM MyTable WHERE Id = {idParam}
- 如果前面的
COUNT
语句returns0,插入这个ID和计数器:
INSERT INTO MyTable(Id, Counter) VALUES({idParam}, {counterParam})
- 如
COUNT
语句returns 1、更新已有记录:UPDATE MyTable SET Counter = Counter + {counterParam} WHERE Id = {idParam}
现在,我知道我必须将整个存储过程包装在一个事务中,并且根据 this MS article 适当的隔离级别将是 SERIALIZABLE
(它说:没有其他事务可以修改数据已被当前事务读取,直到当前事务完成)。如果我这里说错了请指正。
假设我调用了 ID=1 的过程,那么第一个查询将是 SELCT COUNT(*) FROM MyTable WHERE SomeId=1
(第一个事务开始)。然后,在执行此查询后,立即调用 ID=2 的过程(第二个事务开始)。
我不明白的是,在这种情况下,我的存储过程执行期间会锁定多少数据:
- 如果第一个事务的第一个查询 returns 0 条记录,这是否意味着第一个事务没有锁定并且其他事务能够在第一个事务尝试之前插入 ID=1?
- 或者第一个事务是否锁定了整个 table 让第二个事务等待,即使这两个事务永远不会尝试 read/update 同一行?
- 或者第一笔交易是否以某种方式禁止其他人read/write在完成之前只记录ID=1?
如果您的筛选器位于索引上,那么它将被锁定。因此,无论该行是否已经存在,它都会在事务期间被锁定。不过要小心——很容易将行锁变成更糟糕的东西,尤其是完整的 table 锁。当然,这种方式很容易引入死锁:)
不过,我建议采用不同的方法。首先,尝试插入。如果它有效,你就完成了 - 如果它没有,你知道你可以安全地进行原子更新。非常快,非常便宜,非常可靠:)
我开始使用 SQL 服务器数据库,但我很难理解 Transaction Isolation Levels
以及它们如何锁定数据。
我正在尝试完成以下简单任务:
- 在 SQL 存储过程中接受一对整数 [ID, counter]
- 判断ID是否存在于某个table:
SELCT COUNT(*) FROM MyTable WHERE Id = {idParam}
- 如果前面的
COUNT
语句returns0,插入这个ID和计数器:INSERT INTO MyTable(Id, Counter) VALUES({idParam}, {counterParam})
- 如
COUNT
语句returns 1、更新已有记录:UPDATE MyTable SET Counter = Counter + {counterParam} WHERE Id = {idParam}
现在,我知道我必须将整个存储过程包装在一个事务中,并且根据 this MS article 适当的隔离级别将是 SERIALIZABLE
(它说:没有其他事务可以修改数据已被当前事务读取,直到当前事务完成)。如果我这里说错了请指正。
假设我调用了 ID=1 的过程,那么第一个查询将是 SELCT COUNT(*) FROM MyTable WHERE SomeId=1
(第一个事务开始)。然后,在执行此查询后,立即调用 ID=2 的过程(第二个事务开始)。
我不明白的是,在这种情况下,我的存储过程执行期间会锁定多少数据:
- 如果第一个事务的第一个查询 returns 0 条记录,这是否意味着第一个事务没有锁定并且其他事务能够在第一个事务尝试之前插入 ID=1?
- 或者第一个事务是否锁定了整个 table 让第二个事务等待,即使这两个事务永远不会尝试 read/update 同一行?
- 或者第一笔交易是否以某种方式禁止其他人read/write在完成之前只记录ID=1?
如果您的筛选器位于索引上,那么它将被锁定。因此,无论该行是否已经存在,它都会在事务期间被锁定。不过要小心——很容易将行锁变成更糟糕的东西,尤其是完整的 table 锁。当然,这种方式很容易引入死锁:)
不过,我建议采用不同的方法。首先,尝试插入。如果它有效,你就完成了 - 如果它没有,你知道你可以安全地进行原子更新。非常快,非常便宜,非常可靠:)