事务
-
注意:一定要使用 Innodb 存储引擎
-
概述:一组操作的集合,是不可分割的工作单元,会把一个部分当成一个整体来处理,事务会把操作同时提交或者是撤销。要么同时成功,要么同时失败。
-
比如:上云转账1000元给张三,第一,上云账户少1000,第二,张三账户多一千。
事务操作
-
数据准备
drop table if exists account; #创建账户信息表 create table account( id int primary key AUTO_INCREMENT comment 'ID',name varchar(10) comment '姓名', money double(10,2) comment '余额' ) comment '账户表'; insert into account(name, money) VALUES ('上云',4000), ('张三',4000);
未控制事务演示
-
正常转账的情况下
#正常转账的情况下 select * from account;#减少上云账户上的1000元 update account set money = money -1000 where name = '上云'; #增加张三账户上的1000元 update account set money = money + 1000 where name = '张三';
-
异常转账的情况下
select * from account;update account set money = 4000;update account set money = money -1000 where name = '上云'; 出错了update account set money = money + 1000 where name = '张三';
控制事务方式1
-
查看事务提交方式
SELECT @@autocommit1:自动提交 0:手动提交
-
设置事务提交方式
set @@autocommit=0;#设置成手动提交
-
提交事务
commit;
-
回滚事务
rollback;
控制事务方式2
-
开启事务
start transaction 或者 begin;
-
提交事务
commit;
-
回滚事务
rollback;
事务的作用对象
- 只能回滚 insert、delete 和 update 语句,不能回滚 select(回滚 select 没有任何意义),对于
create、drop、alter 这些无法回滚.
事务的四大特征(ACID)
- 原子性(Atomicity):整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)不可分割,要么全部成功,要么全部失败
- 一致性(Consistency)事务完成时,数据保持一致状态
- 隔离性(Isolation):数据库会提供隔离机制,并发不会相互影响和干扰,一个事务不会影响其他事务的运行
- 持久性(Durability):在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚。
并发事务的问题(面试经常问)
- 脏读:一个事务读到另外一个事务还没有提交的数据
- 事务B读取到事务A还没有提交的数据
- 事务B读取到事务A还没有提交的数据
- 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
- 事务A两次读取同一条数据,但是读取到的数据不一样
- 事务A两次读取同一条数据,但是读取到的数据不一样
- 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了 “幻影”。
事务的隔离级别
-
注意:隔离级别越高,数据越安全,但是性能低。需要在性能和安全之间进行取舍。
-
查看隔离级别:
SELECT @@TRANSACTION_ISOLATION;
-
设置隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
-
隔离级别分为全局的和会话级的
- 全局的:对所有会话有效(global)
- 会话级的:只对当前的会话有效(session)
-
演示
-
脏读(read uncommitted 未提交读)
会话1 会话2 use transaction; use transaction; set global transaction isolation level read uncommitted; start transaction; start transaction; insert into account values(2,‘sy’,100); select * from account; rollback; select * from account; -
read committed(已提交读)
会话1 会话2 set global transaction isolation level read committed; start transaction; start transaction; insert into account values(2,‘sy’,100); select * from account; select * from account;(不能查询出数据) commit; select * from account;(查询出数据) -
repeatable read(可重复读)
会话1 会话2 set global transaction isolation level repeatable read; start transaction; start transaction; insert into account values(3,‘xxxxy’,100); select * from account(读不出来) commit; select * from account(能读出来)