【以转账为例】
事务
事务是指满足ACID的一组操作,可以通过Commit提交一个事务,也可以使用Rollback进行回滚。
ACID
1.原子性(Atomicity)
事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。
2.一致性(Consisitency)
数据库在事务执行前后都保持一致性状态。即转账前后,两个人账户总金额不变。
3.隔离性(Isolation)
根据隔离级别,一个事物所作的修改对于其他事务来说是不确定的。
4.持久性(Durability)
一旦事务提交,则其所作的修改将会永远保存到数据库中。
隔离级别
mysql默认的隔离级别是可重复读。
下面的代码所运行的两个事务需要在两个不同的session中执行,开启两个客户端。
1.读未提交 READ UNCOMMITTED
读未提交:事务中的修改,即使没有提交,对其他事务也是可见的。
事务1:
1 set session transaction isolation level read uncommitted; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事务2:
1 set session transaction isolation level read uncommitted; 2 3 start transaction; 4 select * from user; 5 commit;
同时开启事务1、事务2。事务2执行到第4行查看两人账户余额都为100,当事务1执行到第4行,事务2再执行第4行查询操作,可以看到id为1的人账户余额少了100,由此可见事务2在执行过程中可以查看到事务1执行但尚未提交的sql。
2.读已提交 READ COMMITTED
读已提交:
事务1:正在执行中的事务可以读取到其他已提交事务所做的修改。
1 set session transaction isolation level read committed; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事务2:
1 set session transaction isolation level read committed; 2 3 start transaction; 4 select * from user; 5 commit;
同时开启事务1、事务2。事务2执行到第4行查看两人账户余额都为100,当事务1执行到第4行,事务2再执行第4行查询操作,可以看到两人账户中的余额没有改变,由此可见事务2在执行过程中不能查看到事务1执行但尚未提交的sql,即只能读已经提交的事务。
3.可重复读 REPEATABLE READ
可重复度:保证在同一事务中多次读取同样数据的结果是一样的,即正在执行中的事务不能读取到其他已提交事务所做的修改。
事务1:
1 set session transaction isolation level repeatable read; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事务2:
1 set session transaction isolation level repeatable read; 2 3 start transaction; 4 select * from user; 5 commit;
同时开启事务1、事务2。事务2执行到第4行查看两人账户余额都为100,当事务1执行到第4行,事务2再执行第4行查询操作,可以看到两人账户中的余额没有改变,继续执行完事务1,事务1已经提交,此时执行事务2的第4行,发现两人账户中的余额依然分别为100,但在事务1的客户端中查询发现转账已经完成,此时我们提交事务2,然后在事务2的客户端中再次执行查询,此时发现已经转账完成。由此可见事务2在执行过程中不能查看到事务1执行且已经提交的sql,即在事务1过程中,可以重复读取到相同且为改变的值。
4.串行化 SERIALIZABLE
串行化:强制事务串行执行。