事务
事务的概述
事务的概念
- 事务:指的是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么全部成功,要么全部失败(原子性)。
- 事务的特性:
- 原子性 :事务的不可分割性,一个完整事务的各个逻辑单元不能被分割
- 一致性 :事务执行的前后,数据完整性保持一致
- 隔离性 :事务的执行不受到其他事务的干扰
- 持久性 :事务一旦结束,数据就持久化到数据库当中
事务的简单使用
我们有一张用户存储表(account),如下:
userId | userName | money |
---|---|---|
0001 | 张憨憨 | 10000 |
0002 | 李笨笨 | 10000 |
0003 | 王蠢蠢 | 10000 |
现在我们要完成一个转账操作,例如:
张憨憨给李笨笨转账3000元,则需要执行SQL语句如下:
-- 此时我们只是简单的示范,不考虑金钱越界的问题
update account set money = money - 3000 where userName = '张憨憨';
update account set money = money + 3000 where userName = '李笨笨';
那么这两个操作必须同时完成才能完成转账操作,一旦一个失败另一个必须也无法执行。我们需要用到事务操作,具体如下:
#开启事务
start transaction;
[[逻辑单元code]]...
update account set money = money - 3000 where userName = '张憨憨';
update account set money = money + 3000 where userName = '李笨笨';
#提交事务
commit;
#回滚事务,返回最后一个事务执行前的结果
rollback;
事务的隔离级别
-
如果不考虑事务的隔离性,将会引发一些安全问题主要体现在读取数据上( 多个事务并行的时候 ):
- 脏读 :一个事务在执行过程中读取到了另外一个事务未提交的数据,导致查询结果不一致
- 不可重复读 :一个事务在执行过程中读取到了另一个事务已经提交的update的数据,导致多次查询结果不一致
- 虚读 :一个事务在执行过程中读到了另一个事务已经提交的insert的数据,导致多次查询不一致
-
解决上述的问题设置了事务的隔离级别(从上往下隔离级别依次提高,效率依次降低):
- read uncommitted:脏读、不可重复读和虚读都有可能发生。
- read committed:避免脏读,不可重复读和虚读有可能发生。
- repeatable read(mysql默认级别):避免脏读和不可重复读,虚读有可能发生。
- serializable:脏读、不可重复读和虚读都不可能发生。
-
设置隔离级别指令:
SET SESSION TRANSACTION ISOLATION LEVEL read [PARAM];
-
serializable
避免虚读的方式,使用串行化操作,一个事务未进行提交,另外一个事务就不可以执行查询等操作。
Q.E.D.