数据库事务的四种隔离级别
数据库事务的隔离级别有4种,由低到⾼分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。⽽且,在事务的
并发操作中可能会出现脏梦见骨灰 读,不可重复读,幻读。下⾯通过事例⼀⼀阐述它们的概念与联系。
Read uncommitted
读未提交,顾名思义,就是⼀个事务可以读取另⼀个未提交事务的数据。
事例:⽼板要给程序员发⼯资,程序员的⼯资是3.6万/⽉。但是发⼯资时⽼板不⼩⼼按错了数白头发的原因 字,按成3.9万/⽉,该钱已经打到程序员的户
⼝,但是事务还没有提交,就在这时,程序员去查看⾃⼰这个⽉的⼯资,发现⽐往常多了3千元,以为涨⼯资了⾮常⾼兴。但是⽼板及时发
现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。
分析:实际程序员这个⽉的⼯资还是3.6万,但是程序员看到的是3.9万。他看到的是⽼板还没提交事务时的数据。这就是脏读。
Read committed
读提交,顾名思义,就是⼀个事务要等另⼀个事务提交后才能读取数据。
事例:程序员拿着信⽤卡去享受⽣活(卡⾥当然是只有3.6万),当他买单时(程序员事务开启),收费系统事先检测到他的卡⾥有3.6万,
就在这个时候!!程序员的妻⼦要把钱全部转出充当家⽤,并提交。当收费系统准备扣款时,再检测qq屏幕分享 卡⾥的⾦额,发现已经没钱了(第⼆次
检测⾦额当然要等待妻⼦转出⾦额事务提交完)。程序员就会很郁闷,明明卡⾥是有钱的…
分析:这就是读提交,若有事务对数据进⾏更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决
脏读问题。但在这个事例中,出现了⼀个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。
Repeatable read
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
事例:程序员拿着信⽤卡去享受⽣活(卡⾥当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系
统事先检测到他的卡⾥有3.6万。这个时候他的妻⼦不能转出⾦额了。接下来收费系统就可以扣款了。
分析:重复读可以解决不可重复读问题。写到这⾥,应该明⽩的⼀点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻
读问题。因为幻读问题对应的是插⼊INSERT操作,⽽不是UPDATE操作。
什么时候会出现幻读?
事例:程序员某⼀天去消费,花了2千元,然后他的妻⼦去查看他今天的消费记录(全表扫描FTS,妻⼦事务开启),看到确实是花了2千
元,就在这个时候,程序员花了1万买了⼀部电脑,即新增INSERT了⼀条消费记录,并提交。当妻⼦打印程序员的消费记录清单时(妻⼦
事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。
那怎么解决幻读问题?Serializable
Serializable 序列化
Serializable 是最⾼的事务隔离级别,在该级别下,事务串⾏化顺序执⾏,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率
低下,⽐较耗数据库性能,⼀般不使⽤。
四种隔离级别可能导致的问题:
1、Serializable (串⾏化):最严格的级别,事务串⾏执⾏,资源消耗最⼤;
2、REPEAT促进发展 A做人的名言名句 BLE READ(重复读) :保证了⼀个事务不会修改已经由另⼀个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读
取”的情况,但保护环境的画 不能避免“幻读”,但是带来了更多的性能损失。
3、READ COMMITTED (提交读):⼤多数主流数据库的默认事务等级,保证了⼀个事务不会读到另⼀个并⾏事务已修改但未提交的数据,
避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适⽤于⼤多数系统。
4、Read Uncommitted(未提交读) :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。
通俗解释:
脏读:所谓的脏读,其实就是读到了别的事务回滚前的脏数据。⽐如事务B执⾏过程中修改了数据X,在未提交前,事务A读取了X,⽽事务
B却回滚了,这样事务A就形成了脏读。
也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。
不可重复读:事务A⾸先读取了⼀条数据,然后执⾏逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配
了,就是所谓的不可重复读了。
也就是说,当前事务先进⾏了⼀次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应
了不可重复读的语义。
幻读:事务A⾸先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务
A再次搜索发现有N+M条数据了,就产⽣了幻读。
也就是说,当前事务读第⼀次取到的数据⽐后来读取到数据条⽬不⼀致。
mysql默认隔离级别
1.查询mysql全局事务隔离级别
lect @@_isolation;
2.查询当前会话事务隔离级别
lect @@tx_isolation;
mysql默认事务隔离级别为REPEATABLE-READ 可以避免脏读,不可重复读,不可避免幻读
常看当前数据库的事务隔离级别: show variables like 'tx_isolation';
设置事务隔离级别:t tx_isolation='REPEATABLE-READ';
Mysql默认的事务隔离级别是可重复读,⽤Spring开发程序时,如果不设置隔离级别默认⽤Mysql设置的隔
离级别,如果Spring设置了就⽤已经设置的隔离级别
可重复读隔离级别下MySQL是如何解决幻读问题的
本文发布于:2023-04-30 09:31:45,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/fan/90/93327.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |