浅谈事务的四大特性ACID以及脏读,不可重复读,幻读,事务丢失

**

数据的四大特性ACID

**

A.原子性(Atomicity)
是指把事务切成原子,每一个部分都要去认真的去比对,把握。
这样做的原因是:甲给乙转钱,这就是一个事务.我们需要把这个事务需要进行的操作原子化,分步进行。否则的话,可能出现甲给乙转了1000元,但是乙账户没到账的情况发生。所以说里面的每一个环节都需要逻辑判断,只要出现异常就需要回滚。

C.一致性(Consistency)
一致性是指:一个程序从数据库中查询数据的时候,必须要和数据库中的数据保持一致。总不能你银行卡里面只有10000元,但查出来右20000元。
再举个例子,甲和乙在玩转账游戏,他们的钱加起来总共只有1000元,所以不管他们怎么转账,谁给谁转,两个人的钱始终就只有1000.(忽略利息。。。。)

I.隔离性(Isolation)
隔离性是指:当多个用户并发的访问数据库时,那么就要进行隔离,始终只能有一个用户访问,并进行操作。
否则可能发生以下情况:甲有一个老婆乙,夫妻两加起来存款1000元。有一天甲取出这一千元买了一套衣服给乙当礼物。但是与此同时,乙也从这个账户里取出1000元买了一个手表给甲当礼物。这个账户总共就1000,如果不进行隔离的话,那么夫妻两实际就取出了两千。这是不符合常理的。

D.持久性(Durability)
持久性是指:一旦事务被提交到了数据库,那么对数据库中的数据就是持久性的,即使数据库系统出现故障的情况下也不会丢失提交事务的操作。

事物的四种隔离机制

脏读:(读到了未提交的数据,然后未提交的数据被回滚了)
还是举个例子:甲给乙转1000块钱,但是甲还没有提交这个事务,也就是说这个数据并没有到数据库中。但是甲突然发现自己转错人了,回滚了事务。但是乙账户里面已经多了1000元。
这种情况就叫做脏读
解决方式:(禁止读取未提交的数据,就可以解决)

不可重复读:(读到了提交的新事物,这个针对update)
不可重复读是指在对于数据库的某个数据,一个事务查询了多次,但是返回了不同的结果集,原因是:在查询的过程中,另一个事务修改了数据,所以导致查询的数据不一致.

不可重复读和脏读的区别,脏读是读了未提交的数据,不可重复读是读到了另一个事务提交的数据,update后的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如同一个事物前后两次查询同一个数据,期望两次读的内容是一样的,但是因为读的过程中,因为令一个数据写了该数据,导致不可重复读。(解决:如果 一个事物在读的时候,禁止任何事物写。是不是就解决了。)

幻读:(也是读取了新事物,这个针对insert)
在事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取的数据不一致。幻读和不可重复读的区别在于,
不可重复是针对记录的update操作,只要在记录上加写锁,就可避免;幻读是对记录的insert操作,
简单来说就是,甲去查询自己的账户的余额,于此同时乙向甲转了1000,所以甲多次查询会不一致,这种情况叫幻读

第一类事务丢失(回滚丢失)
这一类是事务丢失,就是比如A和B同时在执行一个数据,然后B事物已经提交了,然后A事物回滚了,这样B事物的操作就因A事物回滚而丢失了。
举个例子,比如我有100元。准备买一个东西,花了100元。然后我朋友给我转了1000元。理论上这两个事物正常的话,我应该还有1900元。
但是,比如现在两个A,B事物同时进行,第一步都先查询我余额还有1000元,然后B事物给我转了1000元,提交了,理论上我还有2000元。然后我买东西,100元的,买到一半,我事物回滚,就回滚成了1000元(回滚丢失,就是指B给我转的1000元丢失了)。如果我不回滚(也就是我把那100元的东西买了),我就还剩900元(也就是下面介绍的第二类事物丢失,覆盖丢失)。

第二类事务丢失(覆盖丢失)
覆盖丢失:就是A和B一起执行一个数据,两个人同时取到一个数据,如果A执行事务,然后B也接着执行,那么B就覆盖了A事务,这就叫覆盖丢失。

四种隔离级别

最低的是(Read Uncommitted)未提交读。(写加锁,读不加锁)
写操作加写锁,读操作不加锁。禁止第一类丢失更新,但是会出现所有其他数据并发问题

@Transactional(isolation = Isolation.READ_UNCOMMITTED)

接下来是(Read Commited)提交读。(写加锁,读也加锁)
写操作加写锁,读操作加读锁。禁止第一类丢失更新和脏读。

就是你已经开始读了数据,然后一个事物开始写,然后写的事物不提交的话,是不能进行读的事物,避免了脏读。

@Transactional(isolation = Isolation.READ_COMMITTED)

然后是(Read repeatable)可重复读(写加锁,读也加锁)
对于读操作加读锁到事务结束,其他事务的更新操作只能等到事务结束之后进行。和提交 读的区别在于,
提交读的读操作是加读锁到本次读操作结束,可重复读的锁粒度更大。禁止两类丢失更新,禁止脏读和不可 重复度,但是可能出现幻读.

一个事物读的时候,我们把两次读看成整体,在读的过程中,不允许写的操作,这样就可以禁止不可重复读。就是两次读操作不允许其他事物。

@Transactional(isolation = Isolation.REPEATABLE_READ)
可重复读(会出现幻读)

以上的隔离级别是大部分数据库默认的级别

最高等级的是(Serializable)序列化。(对表级读,写加锁)
读操作加表级读锁至事务结束。可以禁止幻读。

设置数据库的隔离级别

session 表示当前表,global表示整个全局

select @@[session | global].tx_isolation; //查看当前的隔离级别

set [session | global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}

//默认级别是repeatable read
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值