1、什么是事务
一个事务是一个完整的业务逻辑单元,不可再分。
比如:银行转账,从A账户向B账务转账10000,需要执行两条update语句
update t_act set balance = balance - 10000 where actno = 'act-001' ; update t_act set balance = balance + 10000 where actno = 'act-002' ;
以上两条DML语句必须同时成功,或同时失败,不允许一条成功,一条失败!
想要保证以上的两条DML语句(update、insert、delete)同时成功或者同时失败,那么就需要使用数据库的“事务机制” !
2、事务原理
假设一个事儿,需要先执行一条insert,再执行一条update,最后执行一条delete,这个事儿才算完成。
开启事务机制(开始)
- 执行insert语句–>insert.(这个执行成功之后,把这个执行记录到数据库的操作历史当中,并不会向文件中保存-条数据,不会真正的修改硬盘上的数据。)
- 执行update语句—> update…(这个执行也是记录一下历史操作,不会真正的修改硬盘上的数据)
- 执行delete语句---->delete…(这个执行也是记录一下历史操作【记录到缓存】,不会真正的修改硬盘上的数据)
提交事务或者回滚事务(结束)
怎么提交事务,怎么回滚事务?
提交事务:commit;语句
回滚事务:rollback;语句==(回滚永远都是只能回到上次事务的提交点!)==
MySQL默认的事务行为是怎么样的?
MySQL默认情况下是支持自动提交事务的。(自动提交):就是一条DML提交一次!
怎么样才能将MySQL的自动提交事务关闭呢?
先执行如下命令:start transaction ,开启事务,也是将自动提交事务关闭!
在次命令后的指定的DML语句并不会持久化到数据库,等待commit | rollback 操作!
3、事务的特性:ACID
A:原子性(atomicity):事务是最小的工作单元,不可再分。
C:一致性(consistency):事务必须保证多条DML语句同时成功或同时失败。
I :隔离性(isolation):事务A与事务B之间具有隔离。
D:持久性(durability):持久性说的时最终的数据必须持久化道硬盘文件中,事务才算成功的结束。
4、事务的隔离性
将事务A与事务B分别比作教室A,B,然而它们之间的墙就是隔离性,墙越厚隔离级别越高!(这种墙分为四个级别)
- 第一级别:读未提交(read uncommitted):我们当前事务可以读取对方未提交的事务,
- 存在问题:存在脏读(Dirty read)现象,表示读到了脏的数据。
- 第二级别:读已提交(read committed):我们当前事务可读取对方已提交的事务,解决了脏读现象,存在问题:不可重复读。
- 第三级别:可重复读(repeatable read):解决不可重复读,永远读取到的都是开启事务时的数据,==存在问题:读取到的数据是幻像(幻读)==例如:执行一条查询的sql需要从1点3点,那么这条sql读取的一直是1点的数据,即使13点之间存在其他操作,该sql的结果并不会受到影响,类似快照,一直读取的是快照中的数据。
- 第四级别:序列化读/串行化读(serializable):解决了所有问题。 效率低,需要事务排队(类似于synchronized)。
Oracle数据库默认级别:第二级别;读已提交
Mysql数据库默认级别:第三级别,可重复读
5、验证各种隔离级别
对以上各种隔离级别做一个验证
通过命令 select @@tx_isolation;查看当前事物的隔离级别 ! +-------------------+ | @@tx_isolation | +-------------------+ | REPEATABLE-READ | +-------------------+
读未提交(read uncommitted):
#执行如下命令,设置全局的事务隔离级别为读未提交 set global transaction isolation level read uncommitted;
读已提交(read committed):
测试 读已提交(read committed)
#执行如下命令,设置全局的事务隔离级别为读已提交 set global transaction isolation level read committed;
可重复读(repeatable read):
测试:可重复读(repeatable read)
#执行如下命令,设置全局的事务隔离级别为可重复读 set global transaction isolation level read committed;
序列化读/串行化读(serializable):
测试 序列化读/串行化读(serializable)
#执行如下命令,设置全局的事务隔离级别为可重复读 set global transaction isolation level serializable;
文章评论