MySQL事务

目录

1.什么是事务

2.为什么用事务

3.事务怎么用

4.事务的四大特性

4.1 原子性 (Atomicity)

4.2 持久性 (Durability)

4.3 ⼀致性 (Consistency)

4.4 隔离性 (Isolation)

4.4.1 举例说明:

4.4.2 MySQL 事务隔离级别有 4 种:


1.什么是事务

事务(Transaction)是将⼀组操作封装成⼀个执行单元(封装到⼀起),这⼀个执⾏单元要么⼀起执行成功,要么⼀起失败,不会出现执行“⼀半”的情况。

2.为什么用事务

以银⾏转账为例,A 转账 B 转账,那么它的执⾏流程是这样的:

  • A 账户 -500
  • B 账户 +500

试想⼀下,如果执⾏了⼀半,断点了或者程序崩溃了,那么 A 账号的钱就永久消失了?那怎么办?⽤事 务就可以解决,封装成⼀个执⾏单元,要么⼀起成功,要么⼀起失败。

使⽤数据库演示⼀下,准备测试表:

drop table if exists accout; 
create table account(
id int primary key auto_increment, 
name varchar(20) comment '账户名称', 
money decimal(11,2) comment '⾦额'
);
insert into account(name, money) values 
('张三', 5000),
('李四', 1000);

张三给李四转 500 元,操作如下:

-- 张三账户减少2000
update account set money=money-500 where name = '张三'; 
-- 李四账户增加2000
update account set money=money+500 where name = '李四';

假如在执⾏以上第⼀句 SQL 时,出现⽹络错误,或是数据库挂掉了,张三的账户会减少 500,但是李四的账户上就没有了增加的⾦额。

解决方案使用事务来控制,保证以上两句SQL要么全部执行成功,要么全部执行失败。

3.事务怎么用

事务的使⽤步骤有三个:

  1. 开启事务(start transaction)
  2. 执⾏多条 SQL
  3. 提交/回滚事务(commit/rollback)

比如上⾯的张三给李四转账,咱们的事务执⾏ SQL 如下:

-- 开启事务
start transaction;
-- 张三账户减少2000
update account set money=money-2000 where name = '张三'; 
-- 李四账户增加2000
update account set money=money+2000 where name = '李四'; 
-- 提交事务
commit;

 

4.事务的四大特性

事务有4 ⼤特性(ACID),原⼦性持久性⼀致性 和 隔离性,具体概念如下:

4.1 原子性 (Atomicity)

        ⼀个事务中的所有操作,要么全部执行成功,要么全部执行失败。原⼦性是事务最重要的特性,全部执⾏失败并不是不执⾏,⽽是通过逆操作 rollback(回滚)数据。
        实现原理:回滚是逆 SQL 操作:⽐如 A 账户 -500 元的逆操作就是 A 账户 +500 元。

4.2 持久性 (Durability

        事务执⾏完成之后,它所做的所有修改都是永久的(不会丢失)。

4.3 ⼀致性 (Consistency)

        ⼀个事务在执⾏前后数据必须保持⼀种合法的状态,事务总是从⼀个⼀致状态到另⼀个⼀致状态。

4.4 隔离性 (Isolation)

        多个事务并发访问时,事务之间是相互隔离的,⼀个事务不应该被其他事务⼲扰,多个并发事务之间要相互隔离。

4.4.1 举例说明:

        比如宠物店,如果宠物店来了⼀个狗狗,那么是可以正常的处理它的诉求的,⽐如打个疫 苗啊、美个容啊都是可以很顺利的完成的,但是如果⼀个 20 平⽅的宠物商店来了 20 只狗那它们就得 打起来了,这个时候怎么办?把它们装到笼⼦⾥⾯“隔离”起来啊,这和咱们的事务的隔离性是⼀样 
的,都是解决多个事务同时请求的问题的。

4.4.2 MySQL 事务隔离级别有 4 种:

  1. 读未提交(READ UNCOMMITTED):也叫未提交读,该隔离级别的事务可以看到其他事务中未提交的数据。该隔离级别因为可以读取到其他事务中未提交的数据,而未提交的数据可能会发⽣回滚, 因此我们把该级别读取到的数据称之为脏数据,把这个问题称之为脏读
  2. 读已提交(READ COMMITTED):也叫提交读,该隔离级别的事务能读取到已经提交事务的数据, 因此它不会有脏读问题。但由于在事务的执⾏中可以读取到其他事务提交的结果,所以在不同时间 的相同 SQL 查询中,可能会得到不同的结果,这种现象叫做不可重复读
  3. 可重复读(REPEATABLE READ)是  MySQL 的默认事务隔离级别,它能确保同⼀事务多次查询的 结果⼀致。但也会有新的问题,⽐如级别的事务正在执⾏时,另⼀个事务成功的插⼊了某条数 据,但因为它每次查询的结果都是⼀样的,所以会导致查询不到这条数据,⾃⼰重复插⼊时⼜失败 因为唯⼀约束的原因)。明明在事务中查询不到这条信息,但⾃⼰就是插⼊不进去,这就叫幻读 (Phantom Read)
  4. 序列化(SERIALIZABLE)事务最高隔离级别,它会强制事务排序,使之不会发⽣冲突,从而解决了脏读、不可重复读和幻读问题,但因为执行效率低,所以真正使⽤的场景并不多。

 注意

  • MySQL是支持给每个连接客户端单独设置事务的隔离级别的。
  • 查询事务的隔离级别:
    select @@global.tx_isolation, @@tx_isolation;

  • 设置当前事务的隔离级别:

    set session transaction isolation level 隔离级别

脏读:⼀个事务读取到了另⼀个事务修改的数据之后,后⼀个事务⼜进⾏了回滚操作,从而导致 第⼀个事务读取的数据是错误的。

演示:开启另一个客户端2

不可重复读:在⼀个事务中,两次查询同⼀条数据得到了不同的结果就是不可重复读。在⼀个事 务两次查询中间,另⼀个事务把这条数据修改了。

演示

幻读:当同⼀查询在不同时间产⽣不同的结果,就是事务中的幻读问题。例如,⼀个 SELECT 被 执⾏了两次,但是第⼆次返回了第⼀次没有返回的⼀⾏,那么这⼀⾏就是⼀个“幻像”⾏。

演示

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

澄白易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值