引入事务:
一个事务其实就是一个完整的业务逻辑
,它是一个最小的工作单元,是不可再分的。
那么什么是一个完整的业务逻辑呢?
拿现实生活中的银行业务举例,假设转账,从A账户向B账户中转账10000,将A账户的钱减去10000(update语句),将B账户的钱加10000(update语句),这两步操作结合即为一个完整的业务逻辑。
以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。
只有DML语句[insert,delete,update]才会有事务,其他语句和事务无关
事务机制
当业务只需要一条DML语句就能完成,那么事务就没有存在的价值了,因为正是做某件事时,需要多条DML语句结合才能够完成,才需要事务的存在,事务本质就是多条DML语句同时执行,或者同时失败
事务机制的执行过程:
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
事务开启:
insert
insert
insert
delete
update
update
事务结束!
在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中,在事务的执行过程中,我们可以提交事务,也可以回滚事务
提交事务:
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中,提交事务标志事务的结束,并且是一种全部成功的结束
回滚事务:
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件,回滚事务标志着事务的结束,并且是一种全部失败的结束
自动提交机制:
提交事务:commit;语句
回滚事务:rollback;语句[回滚永远都是只能回滚到上一次的提交点]
经过如下测试:
我们得出,MySQL默认情况下是自动提交事务的,即为每执行一条DML语句,则提交一次
这种自动提交实际上是不符合我们的开发习惯,因为每一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全。必须要求同时成功之后再提交所以不能执行一条就提交一条
关闭自动提交机制:
执行下述语句;
start transaction;
人为提交事务:
事务的4个特性:
A:原子性
说明事务是最小的工作单元,不可再分
C:一致性
所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性
I:隔离性
A事务和B事务具有一定的隔离
教室A和教室B之间有一道墙,所谓个隔离性就是指这道墙,A事务在操作一张表的时候,另一个事务B也操作这张表,相当于多线程并发访问同一张表
而A教室和B教室之间所隔的墙,可以很厚,也可以很薄,这就是事务的隔离级别,这道墙越厚,表示隔离级别越高
。
事务和事务之间的隔离级别有哪些?
读未提交:
read uncommitted(最低的隔离级别)
,事务A可以读取到事务B未提交的数据,这种隔离级别存在的问题就是:脏读现象(Dirty Read),即为读到了脏数据,这种隔离级别一般都是理论上的,大多数的数据库隔离级别第二档起步。
验证
:
查看当前MySQL使用的隔离级别:
8.0以下版本使用该命令:
select @@tx_isolation;
设置隔离级别为read uncommitted
执行下述命令:
set global transaction isolation level read uncommitted;
再次查询:
验证过程如下:
读已提交:
read committed
,事务A只能读取到事务B提交之后的数据,这种隔离级别避免了读取到脏数据现象
,但是这种隔离级别不可重复读取数据
,也就是说,在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,3不等于4,称为不可重复读取
这种隔离级别是比较真实的数据,每一次读到的数据是绝对真实的
,Oracle数据库默认的隔离级别是:read committed
设置隔离级别为read committed
执行下述命令:
set global transaction isolation level read committed;
再次查询:
验证过程如下:
可重复读:
repeatable read
,事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的,即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读,它解决了不可重复读取数据的问题,但是它存在会出现幻影读的问题,即为每一次读取到的数据都是幻象,不够真实
设置隔离级别为repeatable read
执行下述命令:
set global transaction isolation level repeatable read;
再次查询:
验证过程如下:
举例:
早晨9点开启了事务,只要事务不结束,到晚上9点,读取到的数据还是那样,读到的都是假象。不够绝对的真实
MySQL中默认的事务隔离级别即为它
序列化/串行化:
serializable(最高的隔离级别),这是最高隔离级别,效率最低,解决了所有的问题,这种隔离级别表示事务排队,不能并发,synchronized,线程同步(事务同步),
每一次读取到的数据都是最真实的,并且效率是最低的`
设置隔离级别为serializable
执行下述命令:
set global transaction isolation level serializable;
再次查询
验证过程如下:
D:持久性
事务最终结束的一个保障—>事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上