MySQL数据库-事务
TCL:即transactinal control language ,事务控制语言。
什么是事务?
一个或一组SQL语句组成的一个执行单元,这个执行单元要么全部执行,要么全部不执行。一个完整的业务逻辑,一个最小的不可分割的单元。在执行单元中每个SQL语句都是相互依赖的,整个单独的单元作为不可分割的整体。如果单元中的每条执行语句一旦执行失败或产生错误,整个单元将会回滚,即回到原始状态,如果单元中所有SQL语句都被执行成功,则事务则被顺利执行。
比如:A用户向B用户转账100元,需要两条SQL语句,第一条将A用户的余额修改为减少100,将B用户的余额修改为增加100,需要将两条SQL语句封装成一个执行单元,保证要么都执行,要么都不执行。
MySQL中存储引擎是指:MySQL中用不同的技术存储在文件或内存中。
在事务的执行过程中,每一条DML操作都会记录到“事务性活动的日志文件中”。
在事务执行的过程中,可以提交事务,也可以回滚事务。
提交事务(commit):清空“事务性活动的日志文件”,将数据持久化到数据库表中。提交事务标志着事务的结束,并且全部成功的结束。
回滚事务(rollback):清空“事务性活动的日志文件”,将执行的所有DML操作全部撤销。回滚事务是事务结束的标志,并且全部失败的标识。
MySQL默认自动提交事务,每执行一条DML语句,提交一次,回滚只能回到上次的提交(commit)点。执行start transaction语句,MySQL会关闭自动提交。
事务的属性(ACID):
1-原子性:事务是一个不可分割的工作单元。
2-一致性:事务的状态必须从一个状态转到另一个状态。
3-隔离性:一个事务的执行不能被其它事务干扰。
4-持久性:一个事务一旦被提交,它对数据库中数据的改变就算永久性的。
只有DML语句才和事务有关系,即insert update delete.
一、事务的创建
1-隐式事务:没有明显的事务开启和结束标记的语句
2-显示事务:事务有明显的开启和结束事务的标记,但是必须要提前设置自动提交功能为禁用。
步骤1:开启事务
set autocommit = 0 ;
start transaction ;
步骤2:编写事务中的SQL语句(select update delete insert)
语句1;
语句2;
…
语句n;
步骤3:结束事务
commit;
rollback;
模拟事务提交执行过程:
create table account(
id int primary key,
name varchar(20) not null,
balance int not null);
insert into account
values(1, '王国栋', 1000),(2,'唐乃乔',1000);
set autocommit = 0;
start transaction;
update account set balance = 500 where name = '王国栋' ;
update account set balance = 1500 where name = '唐乃乔' ;
commit;
模拟事务回滚过程:
set autocommit = 0;
start transaction;
update account set balance = 3500 where name = '王国栋' ;
update account set balance = 100 where name = '唐乃乔' ;
rollback;
二、事务的隔离机制
同时运行多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。
1-脏读:对于两个事务T1和T2,T1读取了已经被T2更新但还没有提交的字段,之后,若T2回滚,则T1读取的数据就是临时且无效的。
2-不可重复读:对于两个事务T1和T2,T1读取了该字段,但是T2更新了该字段,T1再次读取这个字段,值就不同了。
3-幻读:对于两个事务T1和T2,T1从表中读取了一些字段,T2在表中插入了一些新的行,T1再次读取该表发现多几行。
通过设置数据库事务的隔离级别,使它们相互不影响,避免各种并发问题。
MySQL支持四种隔离级别,默认的事务隔离级别为repeatable read,Oracle数据库默认的隔离级别是read committed。
四种隔离级别:
分别为读未提交,读已提交,可重复读, 序列化/串行化
读未提交是最低的隔离级别,序列化隔离级别最高。
读未提交:没有提交就读取到了。
读已提交:已经提交的才能读取。
可重复读:事务结束之前。永远读取不到真实数据,提交了也读取不到,读取的永远都是最初的数据,即假象。
序列化:表示事务排队,不能并发,每次读取的都是最真实的数据。
1-read uncommitted:可以出现脏读,幻读,不可重复读。
2-read committed:避免脏读,出现幻读和不可重复读。
3-repeatable read:避免脏读和不可重复读,出现幻读。
4-serializable:避免脏读,幻读,不可重复读。
savepoint的使用:
savepoint可以和rollback搭配使用,使得事务回滚到该点。
如下只删除id为1的,而id为2的保留原始状态。
set autocommit = 0;
start transaction;
delete from account where id = 1;
savepoint a;
delete from account where id = 2;
rollback to a;