五分钟理解数据库事务引发的安全性问题

       最近面试发现面试官都很容易问关于这方面的问题,所以就稍稍总结了下,希望对正在找工作的小伙伴们有帮助,如何快速的理解并且记住事务引发的安全性问题,从而在面试中取得好的成绩。

本文主要分三个模块来讲解。需要重点理解共享锁/排它锁锁的三要素,事务级别和锁的关系

第一部分:锁的介绍

1.什么是乐观锁?

       通俗的理解,太乐观了,总是认为我们对数据操作时,不会产生冲突问题。也就是说在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了。一般来说数据库不实现乐观锁,需要我们自己去实现。

       乐观锁中常见的实现机制:先给数据表加一个版本(version)字段,操作一次,将那条记录的版本号加1。

2.什么是悲观锁?

       通俗的理解,太悲观了,总是认为我们对数据操作时,会产生冲突问题。也就是说每次操作时,都要通过获取锁才能进行对相同数据的操作。数据库本身实现了悲观锁。

      有哪些悲观锁?

              2.1共享锁:又称读锁,是读取操作创建的锁。其他事务可以并发读取数据,但是不能对数据进行修改,直到释放锁。

                      共享锁SQL实现机制:SELECT ... LOCK IN SHARE MODE;

             2.2 排它锁:又称写锁,如果事务T对数据D加上排他锁后,则其他事务不能再对D加任任何类型的锁。获准排他锁的事务既 能读数据,又能写数据。

                      排他锁SQL实现机制:SELECT ... FOR UPDATE;

              2.3行锁:对数据库中的“读写操作的行”加锁

              2.4表锁:对数据库中的“读取操作的表”加锁

第二部分:安全性问题

       1.脏读:事务A正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中。这时,事务B也访问这个数据,                  然后使用了这个数据。

       2.不可重复读:在一个事务中,多次读取数据时,不能读取到相同的数据内容。事务A读取数据XXX之后未提交事务,此时                   事务B对数据XXX进行了修改,并且B提交了事务,持久化到数据库,此时事务A在次读取XXX数据,发现两次读取内                   容不一致。

       幻读:与不可重复读的差异:不可重复读是事务A读取到了事务B的update行为,虚读是事务A读取到了事务B的insert行为。

第三部分:数据库事务的级别

       数据库的事务级别我们可以理解为按照锁来划分的。主要有3个锁的要素:锁的类型、锁的释放、锁的范围。

      1.锁的类型:共享锁、排他锁。具体介绍看第一部分

      2.锁的释放:2.1在操作数据上释放锁。对数据的读写操作完成后释放锁,此时如果操作数据的这个事务尚未结束,其他事务                             是可以继续操作数据的。

                           2.2在操作数据的事务上释放锁。对数据的读写操作完成后并未释放锁,此时要等操作数据的这个事务结束后,                             其他事务才可以操作这个数据。

      3.锁的范围:3.1对操作的数据上锁。操作哪一行数据,就对哪一行数据上锁。

                           3.2对操作的数据的表上锁。操作那个表的数据,就对那个表上锁。

       一级事务:未提交读(Read uncommitted) 

               原理:锁的类型:读取共享锁

                          锁的释放:读取数据结束,释放锁

                          锁的范围:对读取的数据上锁

               引发的安全性:虚读,不可重复读,幻读

               表现:读取数据未结束时,不释放锁,谁都可以读,但是不能写;

                          读取数据结束,释放锁,但事务尚未结束的时候,其他事务可以随意读写,因为此时锁释放了,事务却没有结                              束,所以什么安全性问题都可能引发。

       二级事务:已提交读(Read committed)

           原理:锁的类型:读取共享锁,修改排他锁

                      锁的释放:读取数据结束,释放锁

                                        修改数据的事务结束,释放锁

                      锁的范围:对操作的数据上锁

           引发的安全性:不可重复读,幻读

           表现:读取操作和一级事务一致

                      修改数据的事务在没有结束时,所有的事务都不可以修改,因为此时排它锁还未释放。因此解决了脏读。

       三级事务:可重复读(Repeatable read)

           原理:锁的类型:读取共享锁,修改排他锁

                      锁的释放:读取数据的事务结束,释放锁

                                        修改数据的事务结束,释放锁

                      锁的范围:对操作的数据上锁

           引发的安全性:幻读

           表现:读取数据的事务在没有结束时,所有的事务都不可以修改数据,因为此时读取锁还未释放。

                      修改数据的事务在没有结束时,所有的事务都不可以修改数据,因为此时排他锁还未释放。因此解决了不可重读

       四级事务:序列化(Serializable)

           原理:锁的类型:读取共享锁,修改排他锁

                      锁的释放:读取数据的事务结束,释放锁

                                        修改数据的事务结束,释放锁

                      锁的范围:对操作的表上锁

           引发的安全性:无(至少上述三种安全性)

           表现:这个比较好理解,对表上锁了,而且都是读写的事务结束以后才释放锁,所以要写的前提是,先拿到锁。什么时                        候能拿到锁?读写数据的事务结束以后。所以能解决目前所知的所有安全性问题。但是这样的话读写效率会很低。

       一二三四级事务原理总结,方便记忆,在此基础上,需要大家充分理解3个锁的要素:

       如果你已经把我的这个看懂了,我相信以后你只需要看一眼这个表就能回想起来他们的关系了,如果在面试的时候遇到关于锁的问题,事务的问题,或者脏读,幻读等问题。别管什么,直接一条龙服务。其实我个人理解,把这三个部分串联起来是最容易理解的。

       

发布了7 篇原创文章 · 获赞 12 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/m0_37892044/article/details/83003671
今日推荐