看了两天Java源码,有点懵、今天翻了一波面试的交流贴,唉,看看各大公司出的那些生怕你通过的面试题、真是觉得自己前途一片昏暗,片昏暗,昏暗,暗。。。
but,习还是要学的,从面试题里看到有问数据库并发问题的,之前上课明明学过数据库原理的,但是看着题目大脑还是一片空白,片空白,空白,白。。。都是之间学习不总结的坑
so,来吧,再学一遍,同时梳理总结一下。好记性不如烂笔头头头头头!
数据库事务的四大特性(ACID)
原子性(Atomicity):是指一个事务中包含的所有操作,要么全做,要么全不做。
一致性(Consistency):指数据库从一个一致性状态转移到另一个一致性状态,只包含已提交的事务,如果某些事务尚未完成被迫中断,而该事务对数据库的修改已经写入物理数据库,此时数据库处于一个不正确的状态。比如A向B转账,不可能A扣了钱,B却没收到。
隔离性(Isolation):是指各个并发事务之间互不干扰。
持久性(Durability):是指事务一旦提交,对数据库的修改是持久的,即使 数据库发生故障也能进行恢复。
数据库事务并发引起的问题
脏读:也叫读脏数据,是指当前事务读取了其他事务还未提交的修改。发生脏读是由于一个事务在提交之前对数据库的修改对其他事务是可见的。举个小栗子:例如A和B在同时卖票,目前系统仅剩一张票,此时尼古拉斯去A处买了一张票,A将数据库中的余票量-1,此时有人去B处买了一张票,B查询数据库发现现在木有票了,于是告诉买者没票了。但是!B处买者走了以后,尼古拉斯突然不想买了,于是A取消之前的操作,并提交事务,此时就导致两处都没有卖出票。这就是因为B读取了A没有提交的数据。
不可重复读:是指一个事务两次读取的结果不一样,这是由于在两次读取的间隔另一个事务修改了数据库并提交。不可重复读和读脏数据的区别是脏读发生在事务提交前,不可重复读是发生在事务提交后。
幻读:事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。不可重复读和幻读的区别在于前者是针对某一条记录,后者是针对一批记录。
以上是一些读问题,还有一些更新问题
更新丢失问题
第一类更新丢失问题:A和B对数据库进行更新,A失败回滚到原点把B对数据库的更新给覆盖掉了。
第二类更新丢失问题:A和B对数据库进行更新,A对数据库的更新覆盖了B对数据库的更新。
对于事务并发引起的问题及一些例子可以参考https://blog.csdn.net/starlh35/article/details/76445267
事务的四种隔离级别
为了保证事务的隔离性,数据库提供了四种隔离级别
读未提交:一个事务在进行写操作时,不允许其他事务进行写操作,但允许其他数据的读操作。这个级别的隔离可以避免更新丢失,但是会导致读脏数据
读已提交:未提交的写事务将会禁止其他事务访问该行。一个这个级别的隔离可以解决读脏数据的问题,但仍然存在不可重复读的问题
可重复读:读取数据的事务禁止其他事务的写操作(避免不可重复读),但允许读事务,写事务则禁止其他一切事务(避免脏读)。该级别仍存在幻读的问题
串行化 :要求事务序列化也就是只能一个接一个执行,该级别的隔离可以避免脏读,不可重复读以及幻读的问题,但是性能不佳,一般很少使用
测试数据库的隔离级别参考https://www.jianshu.com/p/8d735db9c2c0 和 https://www.jb51.net/article/116477.htm一定要看,便于理解。
在mysql中查看当前事务的隔离级别:
select @@tx_isolation;
在MySQL数据库中设置事务的隔离 级别:
set [glogal | session] transaction isolation level 隔离级别名称;或者set tx_isolation=’隔离级别名称;’
好了,先酱吧、
原文地址:https://www.cnblogs.com/April1995/p/9555542.html