一、事务控制语言
事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行
特性:acid
a:原子性:一个事务不可再分割,要么都执行要么都不执行
c:一致性:一个事务执行会使数据从一个一致状态切换到另一个一致状态
i:隔离性:一个事务的执行不会受其他事务的干扰
d:持久性:一个事务一旦提交,则会永久的改变数据库的数据
二、事务创建
1、隐式事务:事务没有明显的开启和结束的标记
例如insert、update、delete语句
2、显示事务:事务具有明显的开启和结束的标记
前提:必须设置自动提交功能为禁用 (set autocommit=0;)
该设置关闭只针对当前会话事务有效,不是永久关闭
查看事务自动提交功能设置:show variables like '%autocommit%';(默认为开启状态)
步骤:
1、开启事务
set autocommit=0; 关闭当前会话自动提交事务功能
start transaction; 开启事务,可选的(只要写了set autocommit=0; 就默认已经开启事务了,所以该行可写可不写)
2、编写事务中的sql语句(select、update、insert、delete)
语句1;
语句2;
...........
3、结束事务
commit; 提交事务
rollback; 回滚事务
# 开启事务
set autocommit=0;
start transaction;
# 事务语句
update stuinfo set age=300 where id=3;
update stuinfo set age=400 where id=4;
select * from stuinfo;
# 介绍事务
commit;
# 开启事务
set autocommit=0;
start transaction;
# 事务语句
update stuinfo set age=300 where id=3;
update stuinfo set age=400 where id=4;
select * from stuinfo;
# 介绍事务
rollback;
三、隔离级别
事务的并非可能会造成脏读、不可重复读,幻读
脏读:读取的是未真正提交update的数据;2个事务同时操作同一条数据,例如数据那么原来命名为“刘备”,事务a修改数据name为“张飞”后未commit提交,这个时候事务b去读会显示为“张飞”,如果事务a rollback事务操作,则读出来是数据是不准确的;
不可重复读:2次读取的数据不一致
2个事务同时操作同一条数据,例如数据那么原来命名为“刘备”,事务a修改数据name为“张飞”后未commit提交,这个时候事务b去读会显示为“张飞”,如果事务a commit事务操作后,事务b再次去读显示的则是“刘备”;
幻读:操作的数据与实际数据条数不一致
数据表中存在3条数据,例如事务a又插入一条数据,但是还未提交,这个时候事务b做不加条件的update操作时,会读取到4条数据,而实际上事务a可能会回滚insert操作,那么事务b 的upate操作就是不准确的,出现了幻读;
查看当前隔离级别:select @@tx_isolation;
设置当前连接隔离级别:set session transaction isolation level 隔离级别;
设置数据库系统全局隔离级别:set global transaction isolation level 隔离级别;
事务的隔离级别:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
read uncommitted | 会 | 会 | 会 |
read committed(oracle默认系统隔离级别) | 不会 | 会 | 会 |
repeatbale read(mysql系统默认隔离级别) | 不会 | 不会 | 会 |
serializable(性能差) | 不会 | 不会 | 不会 |
四、回滚点(需要搭配rollback使用)
set autocommit=0;
start transaction;
delete from account where id=25;
savepoint a; # 设置保存点
delete from account where id=26;
rollback to a; # 回滚到保存点a