大家好,我是金鱼座,一个走在测试领域这片蓝海中, 蹉跎前行的技术渣渣,唯有一直走下去,也许能改变点什么,加油!
最近在工作过程中,遇到一些关于mysql的问题,特别稍微在网上看了下外界工作中中关于数据库相关的面试题目时,发现自己除了最基础的select, delete, updata等操作外,其他一些mysql的理解基本上不了解, 那么这次就通过网上了解来整理下其他相关知识。
首先说下mysql的事务
事务(ACID)
可以想象这个就是一串sql操作的集合,并且这个集合是去共同完成某一个目标,当然这样定义后是否虽然写点东西都能当做事务呢,那肯定不行,事务还需要具有以下特性:
原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )
那么这些特点是代表什么?
原子性(A):事务是最小单位,不可再分
一致性(C):事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败
隔离性(I):事务A和事务B之间具有隔离性
持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)
注意mysql一个特点
在MySQL中,默认情况下,事务是自动提交的,也就是说,只要执行一条DML语句就开启了事物,并且提交了事务
在事务进行过程中,未结束之前,DML语句是不会更改底层数据,只是将历史操作记录一下,在内存中完成记录。只有在事物结束的时候,而且是成功的结束的时候,才会修改底层硬盘文件中的数据
举例:
mysql> start transaction;#手动开启事务
mysql> insert into t_user(name) values('pp');
# 事务成功,执行提交操作
mysql> commit;#commit之后即可改变底层数据库数据
# 事务失败操作 后执行回滚操作
mysql> rollback;
mysql> select * from t_user;
+----+------+
| id | name |
+----+------+
| 1 | jay |
| 2 | man |
| 3 | pp |
+----+------+
3 rows in set (0.00 sec)
上述例子中,从开始一个事务,到执行一个DML(DML(insert、update、delete)语句,再到最后的commit提交就是一次完整的事务,并且需要注意:
commit操作一旦提交那么数据库中相关修改数据库操作的行为就会进行特定操作,此时数据库中的数据已经发生了变化
rollback操作一旦执行, 那么当前执行过的DML就会不执行数据库操作,而数据库会显示最初的样子
上述的例子和操作,在我看来主要跟大家展示理解他的原子性和一致性,那么下面说下关于事务隔离性
事务与事务之间是存在一定的隔离的, 就好比说现在购买东西,A购买苹果和B购买橘子,两者之间并不会存在一定程度的影响,各自完成各自事务
隔离性有隔离级别(4个)
读未提交:read uncommitted
读已提交:read committed
可重复读:repeatable read
串行化:serializable
在看其他人员的关于隔离的说明实例说明时, 一定要明白各个隔离级别实际上你可以理解为两个事物之间的相互影响范围
比如:
读未提交
未提交读的意思就是比如原先name的值是小刚,然后有一个事务Bupdate table set name = '小明' where id = 1
,它还没提交事务。同时事务A也起了,有一个select语句select name from table where id = 1
,在这个隔离级别下获取到的name的值是小明而不是小刚。那万一事务B回滚了,实际数据库中的名字还是小刚,事务A却返回了一个小明,这就称之为脏读。
读已提交
按照上面那个例子,在已提交读的情况下,事务A的select name 的结果是小刚,而不是小明,因为在这个隔离级别下,一个事务只能读到另一个事务修改的已经提交了事务的数据。但是有个现象,还是拿上面的例子说。如果事务B 在这时候隐式提交了时候,然后事务A的select name结果就是小明了,这都没问题,但是事务A还没结束,这时候事务B又update table set name = '小红' where id = 1
并且隐式提交了。然后事务A又执行了一次select name from table where id = 1
结果就返回了小红。这种现象叫不可重复读。
可重复读
可重复读就是一个事务只能读到另一个事务修改的已提交了事务的数据,但是第一次读取的数据,即使别的事务修改的这个值,这个事务再读取这条数据的时候还是和第一次获取的一样,不会随着别的事务的修改而改变。这和已提交读的区别就在于,它重复读取的值是不变的。所以取了个贴切的名字叫可重复读。按照这个隔离级别下那上面的例子就是:
串行化
上面三个隔离级别对同一条记录的读和写都可以并发进行,但是串行化格式下就只能进行读-读并发。只要有一个事务操作一条记录的写,那么其他要访问这条记录的事务都得等着。
此处借用别人对于幻读的理解:
幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。
最后首先感谢网友,参考链接:
https://blog.csdn.net/w_linux/article/details/79666086
https://www.cnblogs.com/flythinking/p/8514133.html
(非常推荐)-->https://baijiahao.baidu.com/s?id=1629344395894429251&wfr=spider&for=pc
(非常推荐)——>https://segmentfault.com/a/1190000014811125