事务及其并发问题

大家好,我是一只学弱狗,记录学习的点点滴滴!

优质文章

优质专栏


事务:事务是由一个或一组SQL语句组成的一个执行单元,这个执行单元要么全部执行,要么全部不执行

事务的ACID属性
  • 原子性(Atomicity):是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
  • 一致性(Consistency):是指事务必须使数据库从一个一致性状态变换到另一个一致性状态
  • 隔离性(Isolation):是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
  • 持久性(Durability):是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,接下来的其它操作和数据库故障不应该对其有任何影响
事务的创建

事务分为隐式事务显式事务

  • 隐式事务:事务没有明显的开启和结束的标记,比如insert、update、delete语句
  • 显式事务:事务具有明显的开启和结束的标记

我们具体来说一下显式事务的创建,它一个前提:必须先设置自动提交功能为禁用,我们执行下面这条语句

SHOW VARIABLES LIKE 'autocommit';

出现下面的结果
autocommit的值
可以看到自动提交(autocommit)的值为ON,为自动开启状态,这也是我们平时所写的的insert、update、delete语句可以代表一个事务,接下来我们先用下面的代码来创建一个表并插入数据

USE test;
DROP TABLE IF EXISTS account;
CREATE TABLE IF NOT EXISTS account(
 id INT,
 username VARCHAR(20),
 salary DOUBLE
);
INSERT INTO account VALUES(1,'Alice',1000);
INSERT INTO account VALUES(2,'Boily',1000);

我们开始创建事务,通过下面的一条语句设置自动提交为禁用

SET autocommit=0;

再看一下autocommit的值
autocommit的值
已经关闭了自动提交,我们继续执行

SET autocommit=0;
UPDATE account SET salary=500 WHERE id=1;
UPDATE account SET salary=1500 WHERE id=2;
COMMIT;

上述代码即一个事务执行之后,我们查看表的内容

达到了预期的结果,我们再来执行下面的语句

SET autocommit=0;
UPDATE account SET salary=1000 WHERE id=1;
UPDATE account SET salary=1000 WHERE id=2;
ROLLBACK;

没有报错,我们再来看下结果

问题出现在COMMIT和ROLLBACK,COMMIT是提交事务,ROLLBACK意为回滚点,大家可以想一下这么一个场景:你双十一购物的时候,看上了一个东西,订单都提交了,当你付钱的时候,发现没钱了,于是呢,这个订单就会失败,而不会提交,大概就是这么一个意思。。。

事务的并发问题

事务的并发问题有下面这几类

  • 脏读:是指对于两个事务T1、T2,T1读取了已经被T2更新但还没有被提交的字段,之后,若T2回滚,T1读取的内容就是临时且无效的
  • 不可重复读:对于两个事务T1、T2,T1读取了一个字段,然后T2更新了该字段,之后,T1再次读取同一个字段,值就不同了
  • 幻读:对于两个事务T1、T2,T1从一个表中读取了一个字段,然后T2在该表插入了一些新的行,之后,如果T1再次读取同一个表,就会多出几行字段

接下来,我们将通过命令行的方式来解读一下上面的三个并发问题,当然,在这之前,我们需要了解一些知识:

在MySQL中,为了避免上面的并发问题,采用了隔离机制,即设置事务的隔离级别,在MySQL中,一共有四种隔离级别,如下

事务的隔离级别

  1. READ UNCOMMITTED
  2. READ COMMITTED
  3. REPEATABLE READ
  4. SERIALIZABLE

我们可以通过下面两条语句来查看隔离级别和设置隔离级别

select @@tx_isolation;#查看隔离级别
set session transaction isolation level 隔离级别;#设置隔离级别

好,我们开始通过命令行的方式,设置不同的隔离级别来了解三种并发问题

隔离级别:READ UNCOMMITTED

打开命令行窗口,查看MySQL默认的隔离级别,如下

可见,MySQL默认的隔离级别是REPEATABLE READ,现在,我们把它设置为READ UNCOMMITTED,如下
设置成功之后,我们查看下表account中的内容,如下

我们开始创建事务,同时,我们再打开一个命令行窗口,如图

这样,就演示了脏读的效果,接下来,我们来演示不可重复读
继续演示幻读

好,对于当隔离级别为READ UNCOMMITTED时的三种并发问题我们就演示到这里。

隔离级别:READ COMMITTED

和前面一样,恢复数据后,我们继续演示
在这里插入图片描述
可见,在这种隔离级别下,可以避免脏读问题,接下来,我们看下不可重复读和幻读
在这里插入图片描述

可见,在这种隔离,仍避免不了不可重复读和幻读

隔离级别:REPEATABLE READ

我们恢复数据,继续演示
在这里插入图片描述
避免了脏读问题,我们看一下不可重复读

这种隔离级别避免了不可重复读,再来看看它对幻读能否避免???
在这里插入图片描述
还是没能避免幻读!!!

隔离级别:SERIALIZABLE

终于,到了最后一个了
我们直接试下看它能否避免幻读在这里插入图片描述
终于避免了,其实在这种隔离级别下,三种并行都能够避免

隔离级别总结
  • READ UNCOMMITTED:出现脏读,不可重复读,幻读
  • READ COMMITTED:避免脏读,出现不可重复读和幻读
  • REPEATABLE READ:避免脏读和不可重复读,避免幻读
  • SERIALIZABLE:避免脏读,不可重复读,幻读
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只学弱狗!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值