事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起想系统提交或撤销操作请求,即这组操作,要么全部执行成功,要么全部执行失败。
注: 默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
select @@autocommit;
set @@autocommit=0;(如果为1是自动提交,如果为0是手动提交)
start transaction 或 begin;
6.2.3 提交事务commit;
6.2.4 回滚事务rollback;
示例:
// 创建账户表
create table acount(
id int auto_increment primary key,
name varchar(10),
money int
);
// 给表中插入数据
insert into acount values(null,'张三',3000),(null,'李四',4000);
//转帐操作(张三给李四转帐1000)
// 查看/设置事务提交方式
select @@autocommit;
set @@autocommit = 0; //设置为手动提交
// 1. 开启事务
start transaction;
// 2. 查询张三账户余额
select * from acount where name = '张三';
// 3. 将张三账户余额减1000
update acount set money = money - 100 where name = '张三';
// 4. 将李四账户余额加1000
update acount set money = money + 100 where name = '李四';
// 如果所有事务执行成功,提交事务
commit;
// 如果有事务执行失败,回滚事务(目前表结构中的数据并没有真正发生变化)
rollback;
6.5 事务四大特性(ACID)
原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
持久性(Durability):事务一旦提交或回滚,他对数据库中的数据的改变就是永久的。
| 问题 | 描述 |
|---|---|
| 赃读 | 一个事务读到另外一个事务还没有提交的数据 |
| 不可重复读 | 一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读 |
| 幻读 | 事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现行数据已经存在,好像出现了’幻影’ |
赃读 首先事务A查询id等于1的数据并进行更新。 事务B此时来查询id等于1的数据,查到的是事务A更新后的数据,但是A事务并没有提交。 事务A 事务B 1) select... id=1; 3) select... id=1; 2) update... id=1; ... 不可重复读 首先事务A查询id等于1的数据,然后继续往下执行。 然后事务B更新id等于1的数据,并提交。 事务A此时再来查询id等于1的数据,发现与之前查出来的数据不一致。 事务A 事务B 1) select... id=1; 2) update.... id=1; ..... 3) commit; 4) select... id=1; 幻读 首先事务A查询id等于1的数据,发现不存在。 然后事务B此时插入id等于1的数据,并进行提交到数据库。 然后事务A接下来开始插入id等于1的数据,但是插入失败,出现主键冲突问题。 接着事务A再来查询数据库中是否存在id等于1的数据,发现还是没有(因为已经解决了不可重复读问题),类似于出现幻觉。 事务A 事务B 1) select... id=1; 2) insert... id=1; 4) insert... id=1; 3) commit; 5) select... id=1;6.7 事务隔离级别
- 事务的隔离级别
| 隔离级别 | 赃读 | 不可重复读 | 幻读 |
|---|---|---|---|
| read uncommitted | √ | √ | √ |
| read committed | X | √ | √ |
| repeatable read(默认) | X | X | √ |
| serializable | X | X | X |
(1)表中数据隔离级别从上到下数据隔离级别越来越高。
(2)serializable数据隔离级别最高,性能最差。
(3)read uncommitted性能最高,但数据安全性最差。
-
查看事务隔离级别
select @@tx_isolation; -
设置事务隔离级别
set [session global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}
-
示例
(1)演示repeatable read事务隔离级别下数据库出现幻读
首先得知当前数据库中的事务隔离级别为不可重复读,然后将事务提交方式设置为手动提交。
然后图中左边和右边都开启事务A和B。
左边的事务A查询worker表中id等于1的数据,发现不存在。
然后右边的事务B往worker表中插入id等于1的数据,并提交。
事务A此时往worker表中插入id等于1的数据,发现插入失败,主键冲突。然后再次查询worker表中id等于1的数据,发现还是不存在,出现幻读。
(2)演示repeatable read事务隔离级别解决了不可重复读
然后图中左边和右边都开启事务A和B。
左边的事务A查询worker表中id等于1的数据。
然后右边的事务B更新worker表中id等于1的数据,并提交。
事务A此时再次查询id等于1的数据,发现没有出现变化。
然而右侧此时再查询id等于1的数据发现是已经改变了的。由此可知,在repeatable read事务隔离级别下,已经解决了不可重复读问题。



