对Mysql可重复读的进一步分析

前言:今天复习数据库的时候,又看到了可重复读,对其实现方式,以及应用中会遇到的一些问题做了思考

参考:

https://blog.csdn.net/qq_29857681/article/details/90576491

https://blog.csdn.net/wwd0501/article/details/85322142

目录

第一章 实现方式

第二章 关于锁与事务的开启

2.1 事务的开启

2.2 锁的开启

第三章 带来的问题


第一章 实现方式

https://blog.csdn.net/qq_29857681/article/details/90576491

 

第二章 关于锁与事务的开启

2.1 事务的开启

对于一个MYSQL数据库(InnoDB),事务的开启与提交模式无非下面这两种情况:

1>若参数autocommit=0,事务则在用户本次对数据进行操作时自动开启,在用户执行commit命令时提交,用户本次对数据库开始进行操作到用户执行commit命令之间的一系列操作为一个完整的事务周期。若不执行commit命令,系统则默认事务回滚。总而言之,当前情况下事务的状态是自动开启手动提交。

2>若参数autocommit=1(系统默认值),事务的开启与提交又分为两种状态:

①手动开启手动提交:当用户执行start transaction命令时(事务初始化),一个事务开启,当用户执行commit命令时当前事务提交。从用户执行start transaction命令到用户执行commit命令之间的一系列操作为一个完整的事务周期。若不执行commit命令,系统则默认事务回滚。

②自动开启自动提交:如果用户在当前情况下(参数autocommit=1)未执行start transaction命令而对数据库进行了操作,系统则默认用户对数据库的每一个操作为一个孤立的事务,也就是说用户每进行一次操作系都会即时提交或者即时回滚。这种情况下用户的每一个操作都是一个完整的事务周期。

2.2 锁的开启

在事务执行过程中,如果有加锁操作,这个锁需要等事务提交时释放。

事务1在t2时刻先执行更新操作,它就会一直持有id=2的锁直到commit;事务2在t3时刻获取会失败。

在正常情况下,我们不开启事务,每进行一次 sql语句如update等操作,会自动将此语句视为一个孤立的事务,也就是说,会自动的进行事务的开启关闭并进行加锁解锁等操作。

个人推测:在不主动开启事物的情况下,执行一条sql语句,会经历开启事务->加锁(如果需要的话)->执行语句->提交事务->解锁这个过程。

第三章 带来的问题

下面是个人的思考:

那会不会有这种情况,当我在一个事务中查询了余额是1000,然后要减少200,那我就设置余额是800,在查和设置之间,我女朋友取了100,然后我设置余额是800,最终余额是800,这样的话就出现了问题,按理说最终余额应该是700。
这种情况该如何避免呢?是在编程的过程中避免么?如不直接设置800,而是直接设置 余额=余额-200 来避免这种情况
如果是在编程的过程中避免的话,那更复杂的情况该怎么办呢?假如我读取到一个值,经过很复杂的计算得到了一个结果,然后在中间过程有个人修改了值,那我这个很复杂的计算不久白费了么,是要加锁什么的解决么

老师的解答:

这种情况比较有效的方式就是加锁,当一个线程在操作数据的时候,另外一个线程只能等待,否则就只能保证操作原子性,也就是直接在sql里面扣减才可以。

也就是说要么加锁,要么把查询和修改变成一个原子操作,即直接在数据库中修改。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值