成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。
1、事务的4大特征ACID
Atomicity Consistency Isolation Durability(原子、一致、隔离、持久)
说明 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁 |
---|---|---|---|---|---|
未提交读 | READ UNCOMMITTED | YES | YES | YEs | NO |
提交读 | READ COMMITTED | NO | YES | YEs | NO |
重复读 | REPEATABLE READ | NO | NO | YEs | NO |
串行读 | SERIALIZABLE | NO | NO | NO | YEs |
2、四种隔离级别分别会产生的问题
ANSI/ISO SQL标准定义了4中事务隔离级别:未提交读(read uncommitted),提交读(read committed),重复读(repeatable read),串行读(serializable)。
对于不同的事务,采用不同的隔离级别分别有不同的结果。不同的隔离级别有不同的现象。主要有下面3种现象:
脏读(Drity Read)
某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
示例:我们可以通过实例来具体的看一下什么叫做脏读,首先我们需要创建一个测试表 test
然后打开双窗口模拟迸发操作~
常用的命令:
查询事务的隔离级别,分别是:全局的、下次事务的、当前事务的隔离级别
show variables like '%storage_engine%'; 查看当前的mysql引擎
show variables like 'autocommit'\G; 查看是否自动提交
select @@global.tx_isolation,@@tx_isolation,@@session.tx_isolation;
set session transaction isolation level READ UNCOMMITTED; 修改当前事务隔离级别
①、两个操作窗口同时开启事务,然后在右侧窗口更新其中的一条记录,左侧去查,我们看一下结果如何?
在此之前我们分别查一下当前事务的隔离级别是什么?
查询结果显示:
当前mysql的隔离级别是:**REPEATABLE-READ** 重复读,这种隔离级别也是大多数mysql的默认的隔离级别,现在我们先测试未提交读(**read uncommitted**),那么我们首先需要将数据库的隔离级别修改一下
方法如下:
set session transaction isolation level READ UNCOMMITTED;
我们在左边的事务中修改某一条记录,然后在右边的事务中我们去查询这条记录看一下会是什么样的结果?
右边事务中我们获取到的值为id=4的name=14,然后我们去回滚左边事务。
注意:在测试的过程中发现了一个bug,那就是我的事务居然没有生效?这是什么原因呢?
答案:在mysql命令行的默认下,事务都是自动提交的,sql语句提交后马上会执行commit操作。因此开启一个事务必须使用begin,start transaction,或者执行 set autocommit=0;
才可以使用的事务控制语句。这块新手可能会遇到这个问题,需要注意一下。(还会有一种问题就是:一定要注意你所操作的当前表的存储引擎是什么?MYISAM不支持事务的,所以需要将表修改为innoDB,查看看方法:show create table test1; 修改方法:alter table test1 engin=innodb(老鸟一般都知道,只是建议小鸟们))
左边事务更新一条字段以后,查询表显示数据已经更新成功,右边事务查询表数据同样显示结果与左侧事务相同,然后我们回滚左边事务,再次查询发现数据还原了,右边事务查询结果显示数据跟上一次查询不一致,这就导致了右边事务之前所查询得到的数据是错误的数据,所以对于右边事务来说就造成了“脏读”。
后面演示请继续参考 Mysql 隔离级别和锁(二)