事务与锁的探讨-自动锁

作者:vkvi 来源:千一网络(原创) 日期:2016-10-20

学了数据库理论知识,我们都知道数据库中有个锁概念,但是我们在软件开发过程中似乎从来没特别指定过锁,那么这个锁到底存不存在呢?

在类似 SQL Server 这类大型数据库管理系统中是存在的,程序中没指定锁的话,就是自动的。

示例一、

代码执行顺序为:

  1. 事务 A 读取记录
  2. 事务 B 读取同一记录
  3. 事务 A 更新同一记录

在数据库管理系统中执行顺序为:

  1. 事务 A 读取记录
  2. 事务 B 读取同一记录
  3. 事务 A 更新同一记录

没啥区别呀,这有啥锁呀?不急,继续看:

示例二、

代码执行顺序为:

  1. 事务 A 更新记录
  2. 事务 B 读取同一记录
  3. 事务 A 更新同一记录

在数据库管理系统中执行顺序为:

  1. 事务 A 更新记录
  2. 事务 A 更新同一记录
  3. 事务 B 读取同一记录

这次仅仅因为第 1 步由读取记录变成了更新记录,所以事务 B 就得等事务 A 执行完了再执行,所以说呀,这个锁是自动的,而且还挺聪明,能够识别加什么样的锁。

事务 B 为什么要去等事务 A 呢?试想一下,如果事务 A 最后 1 步更新时失败,就会导致第 1 步被会撤销(事务的特性就是这样,要么都成功,要么都失败),为了避免事务 B 读取的数据是被撤销的数据,所以就让事务 B 等一等了,等事务 A 完成,确认数据不会被撤销了,再来读取。

小结一下:在事务 A,当执行到 update 时,就会在这里开始加锁,事务 B 若在加锁后执行到 select、update 相同的表时,就会等待事务 A 结束。(注意是执行到 select、update 相同的表时开始等待,并不是事务 B 一开始就等待。)

示例三、

代码执行顺序为:

  1. 事务 A 更新记录
  2. 事务 B 读取另一表的记录
  3. 事务 A 更新另一表的记录(与事务 B 同表)

在数据库管理系统中执行顺序为:

  1. 事务 A 更新记录
  2. 事务 B 读取另一表的记录
  3. 事务 A 更新另一表的记录(与事务 B 同表)

嘿,这回又变了,足见锁的聪明:

它知道事务 A 的第 1 步更新并不与事务 B 冲突,所以事务 B 并没有等待;

事务 A 的最后 1 步本身就位于事务 B 的后面,它更新成功与否不影响事务 B 的脏不脏读问题,所以按顺序执行。

我们在实际使用过程中,如果要求不是很严格,并发量不是很大,大多数也不需要关注上述理论,只需要知道有这么回事即可。但如果并发量很大,要求又高(比如金融),这就必须考虑,此时可以认真阅读一下本文。如果你想亲自测试一下,我们建议用两个线程,再加 Thread.Sleep 让代码执行顺序固定下来,看看最终在数据库管理系统中的执行顺序与代码执行顺序有何差别。

扩展一下

在同一事务中:

1、事务开始

2、更新表记录

3、选取表记录

4、更新表记录(这次失败了,事务撤销)

最终数据库中的表记录没有更新,但第 3 步选出来的记录仍然是第 2 步更新之后的记录。

相关阅读

你前面那位网友看了:微店的登录有点乱?还是出问题了?

▲▲▲嘿,欢迎转载传播本站原创文章,尽量保留来源噢。▲▲▲

文章评论
标题:必填
内容:
本站永远终止与捏造“罪名”不支付广告费的某度联盟合作。
vkvi
vkvi

作者简介: vkvi,致力于 .NET Web 开发、移动开发的技术推广,在 .NET、SQL Server、Windows Server 等方面有深入研究和丰富经验,10 年间共计撰写文章 4000 余篇。 主持金融、国土、农业、电商等多个行业项目执行, 推行“技术提升生产力、人心决定成功率”的管理理论。 联系他