1、什么是事务?
事务是一组不可分割的SQL语句集合,可以撤销。银行转账是最经典的例子,需要用事务保证。不同银行间转账则需要用到分布式事务。
2、事务的四大特性(ACID)
原子性(Atomicity):构成事务的所有操作必须是一个逻辑单元,可以撤销,要么全部完成,要么全部失败。
一致性(Consistency):一个事务执行前后必须处于一致性状态。如转账前A、B账户总余额为1000元,转账后应该也为1000元。
隔离性(Isolation):并发事务之间不能相互干扰。
持久性(Durability):一旦一个事务提交,对于数据库中数据的改变是永久的。
3、事务机制的几个术语
事务(transaction):指一组不可分割的SQL语句。
回退(rollback):值撤销指定SQL语句的过程。
提交(commit):指将要存储的SQL语句结果写入到数据库表中。
保留点(savepoint):指事务处理中设置的临时占位符。你可以对其发布回退,与回退真个事务不同。
4、控制事务处理
A。开启事务 start transcation; begin;
B。回滚事务 rollback;
C。可以回滚的语句:数据操纵语言DML:insert、update、delete
5、事务提交
在事务处理块中,提交不会自动提交(除非使用了会触发隐式提交的语句)。为了明确地提交事务,需要使用commit关键字。
使用commit;语句或者rollback;语句后事务会自动关闭。
隐式提交
会触发隐式提交的语句:数据控制语言DCL:grant、revoke。数据定义语言DDL:create、alter、drop
自动提交
MySQL中的事务是自动提交的,我们可以进行相应的设置
set [session] atuocommit=0; 设置事务不自动提交,session级别,只在单个session上生效
set [session] atuocommit=1; 设置事务自动提交,session级别,只在单个session上生效
set global atuocommit=0; 设置事务不自动提交,全局生效
set global atuocommit=1; 设置事务自动提交,全局生效
show global/[session] variables like 'autocommit'; 查看autocommit模式
关于隐式提交和自动提交的验证
开启autocommit;
select * from t_student;
show variables like 'autocommit';#查看autocommit模式
执行以下语句:
begin;
insert into t_student values('09','刘三','1992-01-09','男');#在事务处理块中不会自动提交
create table t1(id int)charset=utf8; #隐式提交,结束当前事务
insert into t_student values('10','dkas','1990-01-09','男');#自动提交
rollback;#回滚查询9和10两条记录都在
查询:select * from t_student;
关闭autocommit
select * from t_student;
show variables like 'autocommit';#查看autocommit模式
执行以下语句:
begin;
insert into t_student values('09','刘三','1992-01-09','男');#在事务处理块中不会自动提交
create table t1(id int)charset=utf8; #隐式提交,结束当前事务
insert into t_student values('10','dkas','1990-01-09','男');#不会自动提交
rollback;#回滚 查询记录9在,记录10不在
查询:select * from t_student;
6、保留点(savepoint)
在事务处理块中,savepoint x; 设置保留点
回退到保留点:rollback to x;
可以在MySQL中设置任意多个保留点,灵活回退。事务结束保留点自动释放。
7、事务并发引发的问题
脏读:读取了其他事务未来得及提交的修改。
不可重复读:一个事务中相同的两个SQL语句读到的结果不一致。两次读取之间有其他事务对数据进行了修改。
幻读:一个事务中发现了以前没发现的数据。 和不可重复读相比,不可重复读是修改了数据,幻读是增加的数据。
丢失更新:两个事务更新一行数据,最后提交的事务的更新会覆盖前一个事务提交的更新,从而导致了第一个事务更新的数据丢失。
8、事务的隔离级别(设置隔离级别一定要在开启事务之前)
未提交读(read uncommitted):允许其他事务看到本事务没有提交的数据。
可能导致:脏读、不可重复读、幻读
提交读(read committed):一个事务只能看见已经提交的事务所作的更改。
大多数数据库管理系统的默认事务隔离级别都是提交读,但MySQL不是。
可能导致:不可重复读、幻读
可重复读(repeatable read):MySQL的默认事务隔离级别
可能导致:幻读
可串行化(serializable):在读取每一行数据时都加一把锁,在事务提交后释放锁
最高隔离级别,可避免幻读。但是会导致大量锁争用和超时。
以上四种隔离机制,级别逐渐递增,数据一致性也越来越好,但是性能上确实逐渐减低的。