这段时间在整理知识点,查看了网上很多博客文章,但是觉得文章中写的一些概念其实不是那么通俗易懂,可能只是单纯得照搬照抄,所以决定自己梳理一遍,大佬见笑。
一、什么是事务
事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务
一个事务是由批量DML(select、insert、update)语句共同联合完成的,它和业务无关,DML才有事务
举个例子:拿万年说破了的银行转账来说吧,你去银行转1000给张三,这里核心sql其实有两条更新语句,一条是更新你的余额,一条是更新张三的余额,在你存到一半的时候因为一些缘故导致第一条语句执行完了,但是第二条语句出错了,那你账户里平白无故就少了1000,并且张三没有收到转账,怎么办?这个时候就需要事务来支持,出错了就取消第一条语句(要么一起成功,要么失败回滚)。
二、事务的四大特性(ACID)
原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部失败。(银行例子)
一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。(比如你转账1000给张三,但是你账户内只有900,那么这次事务是不成功的)。
隔离性(Isolation):数据库允许多个事务同时对其数据进行读写和修改的能力。
持久性(Durability):事务处理结束后,对数据的修改是永久的,即便出现故障(死机,数据库宕机,断电等)也不会丢失。
三、事务的基本操作
begin/start transaction;//开始事务
rollback;//回滚
commit;//提交
select @@transaction_isolation;//查询当前事务隔离级别
set session transaction isolation level read uncommitted;//设置当前对话事务隔离级别
四、事务的隔离级别
事务有四大隔离级别:
1、read uncommitted(读未提交或者未提交读)(反正我一般只记英文,英文翻译过来其实两个中文叫法都可以),上自己数据库操作演示:
打开两个查询session,然后用select @@transaction_isolation;查询到当前隔离级别,默认为repeatable read;
用set session transaction isolation level read uncommitted;修改为read uncommitted;
另一个窗口也这么操作,使得两个窗口的数据隔离级别都是read uncommitted;
两个窗口分别开启事务(start/begin transaction;);
我这里用的是start,用begin也一样;
第一个窗口执行更新操作;
(原数据)
(更新后的数据)
可以看到已经更新成功了;
然后在第二个窗口中查询,可以看到是能够查询到第一个窗口刚刚更新的数据;
这个时候如果第二个窗口查询结束并且commit,结果给到了系统,但是第一个窗口因为某些原因导致回滚,就会出现问题,第二个窗口查出来的数据其实并不是现在数据库里的数据,而是被其他事物操作造成的脏数据,也被叫做脏读
2、read committed(读已提交)
同样的,修改两个窗口隔离级别为read committed,并且开启事务(前面有我就不重复了);
窗口二先查询;
窗口一更新;
窗口二再查询,这个时候查询不到窗口一更改的数据,解决了脏读;
这个时候窗口一提交事务
窗口二因某些原因又查一遍,发现数据变了,两次查询结果不一致,出现了不可重复读;
3、repeatable read (可重复读)
4、serializable (串行化)