事务理解

什么是事务?事务简单点理解,就是确定我们对数据库中数据的修改是否保留。来确保最终存储数据的一致性。

事务处理遵循四个原则

事务是对数据库的操作,我们平时只要牵扯到**数据的增加、修改、删除,**就需要对其进行事务提交。那么,事务的处理就需要遵循如下四个原则:

  • 原子性:在进行事务提交时,所有的操作要么全部完成,要么全部失败,不能说我们执行了数据的增加,随后又对该数据进行了修改,最后提交事务,不能说增加成功了,修改失败了。

  • 一致性:一致性就是我们操作的数据要保持一致,一致性和原子性有着紧密的联系,像玩游戏可以赠送礼品一样,A和B两个人,A人把自己游戏仓库里的 “宝刀” 送给了B人,那么此时应该是A人的仓库里面要减少一把 “宝刀”,而B人的仓库里面增加一把宝刀。不能说减少了A人的游戏装备成功后,正要增加到B的仓库装备,此时发生了错误,导致B人没有收到赠礼,而A人却白白丢失了一把刀。

  • 隔离性:多个用户访问数据库时,各自的事务处理之间互不影响,而事务的隔离有四种隔离级别,每个隔离级别都有不同的属性。

  • 持久性:一旦进行了事务的提交,则不能回退回事务之前的数据。

并发下的数据库访问问题及解决方案?

为什么需要事务?在一套系统的使用中,肯定是大量的用户同时使用,并发操作访问数据库的情况下,可能会造成数据更新丢失、脏读、不可重复读、幻读问题。

如何解决这个问题?我们在每个人进行数据操作时,做一些规则限定(事务),我们知道事务处理需要遵循四个基本原则,通过事务的隔离性来将每一个不同的session会话隔离开来。而事务的隔离有四种隔离级别,每个隔离级别都有不同的属性。

数据更新丢失问题及解决:
在这里插入图片描述
上图所示,小美和小明在操作同一数据时,导致更新冲突,数据显示不正确。这个时候就有一个锁机制,当小美在进行数据写入时,对该数据进行加锁(排他锁 Exclusive Lock),此时,只要该锁没有被释放(也就是没有提交事务,执行COMMIT),小明无法对该数据进行写入操作。如下图:
在这里插入图片描述
以上操作,就是READ UNCOMMITTED隔离级别,此隔离级别就是在执行数据修改时加入排他锁(Exclusive Lock),执行完毕后释放该锁,其他session会话才可以进行该数据的修改,此时就避免了数据更新丢失问题。但是,此时会引发一个新的问题:脏读

脏读:
在这里插入图片描述
可以发现,READ UNCOMMITTED 隔离级别可以让其他的session会话读取到没有被提交的数据,从而导致小明读取到了错误的数据。

如何解决脏读?
写入数据时,通过排他锁(Exclusive Lock)可以解决数据更新丢失问题,那是不是也可以在读取数据时加入锁,如果在读数据时也使用排他锁,太占用数据库资源,此时,就有一个新的约定,共享锁(Share Lock),该锁在数据读取完成后就立马被释放

在这里插入图片描述
此时就避免了脏读的发生,这样的处理操作在数据库中为第二隔离级别:READ COMMITTED隔离级别,避免了其他的session可以读取到没有被提交事务的数据。
通过第二隔离级别READ COMMITTED在读数据时,加入共享锁(Share Lock),读取完成后立马释放掉该锁,写数据时和第一隔离级别一样,很好的解决脏读问题,但是又冒出了一个新的问题:不可重复读。

什么是不可重复读?
在这里插入图片描述
此时,不可重复读的原因就是小美读取完数据后立马释放掉读锁导致,解决这样的问题,还是需要在读数据时一直锁住,直到释放。此时就有了第三个事务隔离级别REPEATABLE READ ,可以来解决掉不可重复读、脏读、数据更新丢失问题

如何解决不可重复读?
在这里插入图片描述
REPEATABLE READ事务隔离级别在MySQL数据库中为默认的隔离级别,可以解决之前遇到的所有问题。但是此时又有一种不一样的情况,幻读

幻读?
在这里插入图片描述
幻读就是当一个人去修改表中所有的数据,之后另外一个session去新增一条数据,之后修改的人去看自己修改的数据时,发现有没有修改成功的,这样的数据就叫做幻读

要想解决幻读问题,就要使用事务隔离级别中的大招Serializable(串行化),所有的session操作,都需要等待上一个执行完成后,才可以进行数据操作,这样的隔离级别是最高的,同样,也是最消耗服务器性能的隔离级别,在实际开发中,不推荐使用此事务隔离级别。

总结:

事务处理遵循四个原则:原子性、一致性、隔离性、持久性

并发访问数据库会造成:数据更新丢失、脏读、不可重复读、幻读问题

事务四个隔离级别
READ UNCOMMITTED:写数据时加入排他锁(Exclusive Lock)

READ COMMITTED:写数据时加入排他锁(Exclusive Lock),读数据时加入共享锁(Share Lock),读完数据后立马释放掉读锁。

REPEATABLE READ:写数据时加入排他锁(Exclusive Lock)读数据时加入共享锁(Share Lock),读完后不会立马释放掉读锁。

SERIALIZABLE:串行化,需要等待上一个事务处理完成后,才执行,所牺牲代价最高

不同隔离级别所解决问题?

隔离级别数据更新丢失脏读不可重复读幻读
READ UNCOMMITTEDYNNN
READ COMMITTEDYYNN
REPEATABLE READYYYN
SERIALIZABLEYYYY
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐