1. 什么是事务
- 事务(Transaction)是将?组操作封装成?个执行单元(封装到?起),这?个执行单元要么?起执行成功,要么?起失败,不会出现执行“?半”的情况。
- 一个最小的执行单元;通常一个事务对应一个完整的业务(例如银行的转账业务,只有转出者金额的减少对应到接收者金额增多这样一个不会从中间断开的一个动态平衡的过程,也就是一个最基本的最小工作单元)。
- 数据库引擎:InnoDB 才支持事务, MyISAM 不支持事务。
- 一个完整的业务需要批量的 DML (insert、update、delete) 语句联合完成。
2. 理解事务 - (用转账操作示例)
以银?转账为例,A 转账 B 转账,那么它的执?流程是这样的: > A 账户 -500 > B 账户 +500 试想?下,如果执?了?半,断点了或者程序崩溃了,那么 A账号的钱就凭空消失了? 那怎么办??事务就可以解决,封装成?个执?单元,要么?起成功,要么?起失败。
演示:有如下这样一个状态,张三原本有1000元,李四有500元 张三给李四转 500 元,操作如下:
update account set money=money-500 where name = '张三';
update account set money=money+500 where name = '李四';
假如在执?以上第?句 SQL 时,出现网络错误,或是数据库挂掉了,张三的账户会减少 500,但是 李四的账户上就没有了增加的?额。
所以: 以上两台DML语句必须同时成功或者同时失败。 最小单元不可再分,当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下;这个记录是在内存中完成的; 当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步。 若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务。
3. 事务的使用
事务的使用步骤有三个:
- 开启事务 (start transaction) [ mysl 8之前使用的是start transaction, mysql 8 之后使用的是 begin ]。
- 执?多条 SQL。
- 提交 / 回滚事务 (commit / rollback)。
?如上?的张三给李四转账,咱们的事务执? SQL 如下:
start transaction;
update account set money=money-500 where name = '张三';
update account set money=money+500 where name = '李四';
commit;
4. 事务的四大特性(ACID)
- 原子性(Atomicity) : ?个事务中的所有操作,要么全部执?成功,要么全部执?失败。
- 一致性(Consistency) : ?个事务在执?前后数据必须保持?种合法的状态,事务总是从?个?致状态到另?个?致状态。
- 隔离性(Isolation) : 多个事务并发访问时,事务之间是相互隔离的,?个事务不应该被其他事务?扰,多个并发事务之间要相互隔离。
- 持久性(Durability) : 事务执?完成之后,它所做的所有修改都是永久的(不会丢失)[内存的数据持久到硬盘文件中]。
MySQL 事务隔离级别有 4 种(重要)
- read uncommitted
1. 读未提交
2. 在此隔离级别中,事务A未提交的数据,事务B可以读到。
3. 这里读取到的数据叫做“脏数据”。
4. 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
eg: 该隔离级别因为可以读取到其他事务中未提交的数据,?未提交的数据可能会发?回滚, 因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读。
- read committed
1. 读已提交
2. 事务A和事务B并行,事物A提交的数据,事物B才能读取到。
3. 可以解决脏读的问题,也就是事务A提交了的数据,事务B才可以读到。可以避免“脏数据”
4. 但他存在不可重复读的问题。
不可重复读: 在一个事务中使用相同的SQL执行了两次,得到了不同的结果(在?个事务两次查询中间,另?个事务把这条数据修改了)
5. Oracle 的默认隔离级别。
- repeatable read
1. 可重复读
2. 事务A和事务B并行时,事务B读取不到事务A提交的数据。
3. 可以重复读取数据。
4. 读已提交一般来说针对的是只有查询的情况。他不可重复读。
而此事务隔离级别可重复读在查询时可以有效隔离开来两个事务,在事务A修改了数据,事务B查询是查询不到的
但是,如果此时在事务B中去拿取事务A中操作过的数据,
原本事务B虽然没有,但是也是可以对这些数据进行操作的。
这个就叫做“幻想读”。
6. MySQL 默认事务隔离级别。
- serialzable
1. 序列化
2. 事务A 和事务B,事务A在操作数据时,事务B只能排队等待。
3. 事务A和事务B是一个本来可以并行的操作将它“串行化”了。
虽然每次读到的都是数据库中实实在在的数据,但是这个事务隔离级别对于用户的体验极差。
4. 只有一个事务进行提交或者回滚了,下一个事务才能执行。
- MySQL 查询事务隔离级别
select @@global.tx_isolation,@@tx_isolation
- 设置当前客户端的事务隔离级别
set session transaction isolation level 事务隔离级别
- 隔离级别与一致性的关系
|