SQL Server:事务锁定表是否会影响其他用户?

3

当我运行多个查询时,事务是否会锁定我的表?

例如:如果另一个用户在同一时间尝试发送数据,而我正在使用事务,会发生什么?

还有,我如何避免这种情况,但同时确保所有数据已成功插入数据库?

Begin Tran;
    Insert into Customers (name) values(name1);

    Update CustomerTrans 
    set CustomerName = (name2);

Commit;

1
这就是事务的作用,它们会锁定表。你无法避免表锁定,因为这是设计上的要求。 - Thom A
https://dev59.com/yWcs5IYBdhLWcg3wu2jS - DeshDeep Singh
你的更新语句中没有where子句,这就是为什么每次都会更新整个表,从而锁定整个表。尝试在更新语句中添加某种where子句。 - M.Ali
1
SQL Server事务具有ACID属性,数据永远不会处于未完成状态。只要您使用事务,就不必担心数据被留下一半或损坏。 SQL Server事务的ACID属性确保“所有都完成或什么都没有完成”。在这方面,您将不得不信任SQL Server。 - M.Ali
@daasssa,很大程度上取决于锁定的粒度。由于您在UPDATE语句中没有WHERE子句,因此表中的每一行都将被更新并锁定,直到事务提交。但是,如果您有一个WHERE子句和有用的索引,那么只有这些行会被锁定。 - Dan Guzman
显示剩余5条评论
2个回答

1

你需要聪明地实现事务。以下是一些与性能相关的要点:

  1. 乐观/悲观锁定。在悲观锁定中,整个表都被锁定。但在乐观锁定中,只有特定的行被锁定。
  2. 隔离级别为已提交读/未提交读。当表被锁定时,它取决于您的业务场景是否允许您使用 NoLock 进行脏读取。
  3. 尝试在更新中使用 where 子句并进行适当的索引。对于任何重要的查询,请检查查询计划。
  4. 事务超时应该非常短。因此,如果表被锁定,则应抛出错误,并在 catch 块中重试。

这些是你可以做的几点。


2
第二个选项通常是在更大的环境中的解决方案,特别是对于针对稀疏更新/历史数据进行报告的存储过程。不幸的是,人们经常将使用NO LOCK视为性能提升,而实际上它是一种“最后手段”机制,用于避免死锁。 - Ross Bush

0

你无法避免多个用户向数据库加载数据。每次单个用户请求使用表时锁定并不可行也不聪明。实际上,你不必担心这个问题,因为数据库本身会提供机制来避免这种问题。我建议你了解ACID属性。

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

可能发生的是,你可能会遭受幽灵读取,基本上是指除非插入数据的用户提交,否则你无法读取数据。即使你已经完成插入数据但没有提交,也有很大的机会看不到更改。

DDL操作(如创建、删除等)本身在最后提交。然而,DML操作(如更新、插入、删除等)在最后不会提交。


展示事务不会阻止其他用户在同一表中使用事务,对吗? - daa sssa
根据锁定类型的不同,有不同的锁定范围。从单个寄存器、行到整个表格。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接