数据库事务:我们可以仅阻止一条记录,而不阻止整个表吗?

时间:2018-07-06 08:14:35

标签: c# sql sql-server dapper

我正在尝试将数据插入SQL Server数据库的Wallets表中。 同时可能有很多请求,因此由于敏感信息,我不得不使用事务。

工作流程如下:

  1. 读取用户的钱包金额

  2. 根据先前收到的数据插入新记录

我尝试了不同的隔离级别,但是在所有情况下,事务都会阻塞整个表,而不仅仅是我正在使用的记录。甚至ReadUncommittedRepeatableRead都会阻塞整个表格。

是否可以仅阻止正在处理的记录?


让我详细说明: 我在表中不使用任何索引

工作流程(将C#转换为SQL)如下:

1)从余额中选择* 2)插入... INTO余额

3 个答案:

答案 0 :(得分:1)

当您要在select语句中锁定一行或多行以用于将来的更新语句时,使用UPDLOCK

Ttransaction-1:

BEGIN TRANSACTION

SELECT * FROM dbo.Test WITH (UPDLOCK) /*read the amount of the user's wallet*/
/* update the record on same transaction that were selected in previous select statement */

COMMIT TRANSACTION

Ttransaction-2:

BEGIN TRANSACTION

/* insert a new row in table is allowed as we have taken UPDLOCK, that only prevents updating the same record in other transaction */

COMMIT TRANSACTION

答案 1 :(得分:1)

不可能处理锁升级过程(行-页面-表-数据库)。不幸的是,它会自动生成。但是,如果发生以下情况,您将获得一些积极的效果

  1. 减少查询中使用的数据量

  2. 通过提示,索引等优化查询

对于INSERT INTO TABLE提示with (rowlock)可以提高性能。

此外,select语句使用共享(S / IS)锁定类型,该类型不允许任何数据更新,但不会阻止读取。

答案 2 :(得分:1)

您应该使用乐观锁定。那只会锁定当前行。不是整个桌子。

您可以阅读以下链接以获得更多参考信息:-

optimistic locking

Optimistic Concurrency