目录
概要
上面我们介绍了集中并发事务执行过程中可能会遇到的问题,这些问题有轻重缓急之分,我们按照问题严重性来排一下序
脏写>脏读>不可重复读>幻读
隔离级别
我们愿意舍弃一部分隔离性来获取一部分性能,在这里体现在:设立一些隔离级别,隔离级别越低并发问题越多,sql标准中设立了4个隔离级别。
READ UNCOMMITTED(读未提交)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。不能避免脏读,不可重复读,幻读。
READ COMMITTED(读已提交)
它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这是大多数程序库系统的默认隔离级别(但不是mysql)的。可以避免脏读,但不可重复读,幻读仍然存在。
REPEATABLE READ(可重复读)
事务A在读到一条记录后,此时事务B对该数据进行了修改提交,那么事务A再读取该数据,读取到的还是原来的数据内容,可以避免脏读,不可重复读,但是幻读仍然存在。这也是mysql的默认隔离级别。
SERIALIZABLE(可串行化)
确保事务可以从一个表中读取相同的行。在这个事务持续期间,禁止其他事务对改变执行插入、更新、删除操作。所有的并发问题都可以避免。但性能时分低下。能避免一切并发问题。
sql标准中规定,针对不同的隔离级别,并发事务可以发生不同严重程度问题,具体如下:
脏写为什么没有涉及到呢?你为脏写这个问题比较严重,不论哪种隔离级别都不允许脏写的发生。
针对mysql关于事务的介绍
mysql支持四种全部隔离级别
不同的数据库厂商对sql标准中规定的四种隔离级别支持不一样。比如Oracle就只支持read committed(默认)和serializable。mysql虽然支持四种隔离级别,但与sql标准中规定的各级隔离级别允许发生的问题有些出入,mysql在repeatable read隔离级别下是可以禁止幻读问题发生的。
手动修改mysql事务隔离级别
#查看隔离级别的 ,mysql5.7.20的版本之前
show variable like 'tx_isolation';
#mysql5.7.20版本之后
show variables like 'transaction_isolation';
#或者不同mysql版本中都可以使用
select @@transaction_isolation;
通过下面的语句修改事务的隔离级别
set [global|session] transaction isolation level 隔离级别;
#其中,隔离级别格式:
read uncommitted
read committed
repeatable read
serializable
或者
set [global|session] transaction_isolation=隔离级别;
#其中,隔离级别格式:
read-uncommitted
read-commited
repeatable-read
serializable
关于设置时使用global或session的影响
使用global的话则:
①当前已经存在的回话无效
②只对执行完该语句之后产生的回话起作用
使用session的话则:
①对当前回话所有后续事务有效
②如果在事务间执行,则对后续的事务有效
③该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务
如果在服务器启动时想改变事务的默认规则,可以修改启动参数transaction_isolation的值。比如,transaction_isolation=serializable,那么事务的默认隔离级别就从原来的repeatable-read变为了serializable。
小结
数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰成都,隔离级别越高,数据一致性就越好,但并发越弱。