一.事务概念与特性
1. 事务(Transaction)概念:是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
2.事务特性:
原子性(Atomicity):事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
一致性(Consistency):事务在完成时,必须使所有的数据都保持一致状态。
隔离性(Isolation):多个事务同时执行时,他们之间是互不干扰的。
持久性(Durability):一旦事务提交成功,它引发的变化也将永远保存下来,硬件与应用程序发生错误也不能改变。
二.事务并发时会出现什么问题呢?
1.脏读:一个事务读到另外一个事务未提交的更新数据。
2.不可重复读:一个事务读另外一个事务已提交的更新数据。
3.幻读:一个事务读到另一个事务已经提交的新插入的数据。
三.四种隔离级别
1.读未提交数据(Read Uncommited):一个事务在执行过程中可以看到其他事务没有提交的新增的记录,而且能看到其他事务没有提交的对已有记录的更新。
2.读已提交数据(Read Commited):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已提交的对已有记录的更新。
3.可重复读(Repeatable Read):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他事物对已有记录的更新。
4.串行化(Serializable):事务执行的时候不允许别的事务并发执行。
四.隔离级别实例
1.将隔离级别设置为读未提交数据,并开启两个客户端A,B
A客户端:
set tx_isolation='read-uncommitted';
select @@tx_isolation;
start transaction;
select * from student limit 0,5;
B客户端:
这时在通过A客户端进行查看信息,会发现Id为2的记录已经更新:
select * from student limit 0,5;
在B客户端将更新事务回滚了,仍然为提交:
在A客户端事务里面也能看到B客户端事务未提交的数据
select * from student limit 0,5;
结论:脏读意味着在事务A中,事务B虽然没有提交数据,但是B事务中任何一条数据改变了,事务A均可以看到!
2.将隔离级别设置为读已提交数据,并开启两个客户端A,B
注释:这个级别是大多数数据库默认的隔离级别,但是MySQL不是,它默认为reaptable-read.
A客户端事务:
set tx_isolation='read-committed';
select @@tx_isolation;
start transaction;
select * from student limit 0,5;
B客户端事务:
回到A客户端事务,查看发现不能其它事务更新数据的变化。
随后将B客户端的更新提交了。
再次回到A客户端事务:
结论:read committed隔离级别下,A事务查看不到其它事物没有提交的更新数据。
3.将隔离级别设置为可重复读,并开启两个客户端A,B:
注释:此级别确保同一个事务的多个实例在并发读取数据时,会看到同样的数据行;此级别可能会出现问题--幻读
:当一个用户在读取某一个范围的数据行时,另外一个事务又在该范围插入了新行,当用户再次读取该范围的数据行时,会发现
有新的幻影行。
A客户端事务:
B客户端事务:
再次回到A客户端事务,这时即使B事务已经提交,但是A事务是看不到更新数据的变化。
这是因为事务A的事务还没有提交,A事务结束后,便可以看到B事务提交更新数据的变化。
结论:可重复读隔离级别下,虽然B事务的数据更新事务已经提交,但是A事务没有提交前,无法看到B事务完成的数据更新产生的变化。
4.将隔离级别设置为可串行化,并开启两个客户端A,B
注释:这是隔离的最高级别,它在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
A客户端事务:
B客户端事务:
结论:可串行化隔离级别下,事务是不能交叉处理执行有交集数据的。