今天来聊聊mysql面试里常见的事务的知识(这里所说的都是Innodb下的事务,MyISAM他也不支持事务不是)
什么是事务?为什么需要事务?
所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。 为什么需要事务呢?例如 :银行转账的问题,从一个账号扣款并使另一个账号入账,这两个操作要么都 执行,要么都不执行。所以,应该把它们看出一个事务。
事务的四大特性 (ACID),问你什么是ACID要能说出来
大概聊聊各个都是什么意思,网上资料也很多可以自行查阅
事物结束后系统状态是一致的,数据不能平白无故的产生,也不能平白无故的消失
(如:微信好友间的转账服务,你的朋友向你转账100元,此时你的账户余额少了100,你的朋友多了100,但你们最终的余额总和是与转账前保持一致的~!不能是你转了100之后,你朋友那只多了50,这样前后不一致)当事务提交后,数据应该永久被保存到数据库中,即使发生了灾难性后果,数据也不会丢失
(简单说就是,将数据存入到磁盘中~!)下面聊聊开启事务的步骤
- #步骤一:开启事务(可选)
- start transaction;
- 或者begin; 我选begin哈哈哈因为简单
-
- #步骤二:编写事务中的sql语句(insert、update、delete)
-
- #步骤三:结束事务
- commit; #提交事务
-
- # rollback; #回滚事务:就是事务不执行,回滚到事务执行前的状态
注意:开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中,好比操作了一个虚拟的数据库一样。
执行commit之后,才是将缓存中的数据变更维护到物理表中
比方说我开启事务之后,新增了一条数据,然后写一个修改的sql执行之后发现自己修改错了,这时候rollback回滚一下,这时候就回到你新增完数据的那个阶段了,你再重新去写正确的修改的sql就可以了,最后commit之后,中间写的所有sql才会真正的执行到数据库。
最后着重来聊聊隔离性的内容
事务并发时可能会出现一些问题
比方说两个人同时操作这个数据库,对表的数据进行修改,可能出现A在操作表中的数据,B也同样在操作表,那么就会出现并发问题,对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采用必要的隔离机制,就会发生以下各种并发问题。
针对这些问题,我们就需要采取一些手段去避免,mysql数据库系统提供了四种事务的隔离级别,用来隔离并发运行各个事务,使得它们相互不受影响,这就是数据库事务的隔离性。
mysql默认的是第三个级别 可重复读,一般来说第二个和第三个用的最多
在未提交读下,也就是级别最低,并发操作时A对表数据进行的任何更改,即使还没有commit提交,B也立马就可以看到,几乎就是共享数据了,互相是透明的,在此级别下脏读、幻读、不可重复读等问题都会出现
在提交读下,A对表数据做的修改在还没commit的时候,B看不见任何改变,但只要A commit提交了,B就可以看到了。此级别下解决了脏读的问题,存在幻读和不可重复读(同时,这也是大多数数据库默认的事务隔离机制)
在可重复读下,A对表数据做的修改,在commit之后A事务结束,数据已经改了,但是B这个事务执行过程中看到的仍然是之前表未改的状态,(就是感觉很怪,明明数据改了但是我就是读不到,感觉出现了幻觉,这就是有幻读问题)此级别下解决了脏读和不可重复读的问题,但仍然存在幻读的问题(同时,这是MySQL默认引擎InnoDB引擎的默认事务隔离级别)
在可串行化下,此级别下脏读、幻读已经不可重复读等问题都将不复存在,在此级别下每条操作命令都必须等到上一条命令执行完毕后才可以开始执行,此时我们的数据库可以看成是一个单线程的程序,数据是绝对安全的,但却严重影响程序的运行效率,只有但数据安全性的要求大大高于运行效率要求时我们才使用该隔离级别
下面是一些有关mysql隔离相关的命令
查看当前会话隔离级别:
SELECT @@SESSION.transaction_isolation;
查看系统隔离级别:
SELECT @@GLOBAL.transaction_isolation;
设置隔离级别:
- # 设置全局隔离级别
- set global transaction isolation level REPEATABLE READ;
- set global transaction isolation level READ COMMITTED;
- set global transaction isolation level READ UNCOMMITTED;
- set global transaction isolation level SERIALIZABLE;
- #设置会话隔离级别
- set session transaction isolation level REPEATABLE READ;
- set session transaction isolation level READ COMMITTED;
- set session transaction isolation level READ UNCOMMITTED;
- set session transaction isolation level SERIALIZABLE;
对于MySQL就讲到这里啦,若文章存在错误还望各位读者指出~