数据库锁解决并发问题
问题描述: 一个优惠券活动,用户可以领取优惠券,但是一个优惠券活动领取数量有限制,所以用户在领取的时候就需要先统计一下以领用的优惠券数量。 然后在生成这张优惠券领取记录。那么此时就会出现并发问题,当多个用户领取同一个优惠券活动的时候,他们统计的优惠券已领数量小于限定可领取数量,所以都可以执行生成 优惠券领取记录的操作,但是剩下的可领取数量可能小于这些用户数量。
如何来解决这个问题呢,首先我们会想到,在程序中使用synchronized关键字来锁住领取优惠券的方法,那么就可以实现,当一个人在领取优惠券的时候其他人等待,但是程序 都是分发到多台服务器的,在分布式的情况下,这种方法并没有效果,因为程序中所能做到的只是锁住单台服务器上面的操作。
既然程序中无法实现,那么我们就想到利用数据库来实现,因为我现在做的这个项目,数据库是没用从库的,只有一台数据库服务器,如果数据库也分布式了,那就要另求它法了。
想到用数据库解决后,首先想到的是利用事务的原子性来解决,就是统计已领用数量的操作和生成优惠券记录的操作合成为一个事务,表面上感觉可以了,但其实这样做也是错误的。 因为多个事务同时处理时,情况也是一样的,同样会出现并发问题。
所以单单利用事务还是不行的,还必须使用数据库的锁机制。
InnoDB实现了以下两种类型的行锁。
共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁(可以读不能写)。
排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁(不能读也不能写)。
锁的范围:行锁: 对某行记录加上锁 ; 表锁: 对整个表加上锁
此处我们需要使用的是排它锁,就是当一个事物在进行操作的时候,其他事物不能去统计已经领取优惠券的数量,只有领取完成之后才能统计。锁的范围是行。
使用排他锁的方法其实是悲观锁机制,我们还有乐观锁,接下来就先介绍下二者区别。
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。 悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。
乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
乐观锁不能解决脏读的问题。 乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。 可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时, 数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。
如果使用乐观锁的方式,我们就需要给数据库有当前优惠券活动已领取数量的字段,每次我们修改这个字段的值时对其就行判断,如果他小于可领取数量,那么久可以插入 这条优惠券记录。这样判断和更新是在同一条sql中,这样就利用一条sql的原子性,避免并发冲突。
reference:
MySQL中SELECT+UPDATE处理并发更新问题解决方案
事务处理和锁定语句
转载于:https://www.cnblogs.com/luojianqun/p/6511734.html
数据库锁解决并发问题相关推荐
- 乐观锁与悲观锁——解决并发问题
引言 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突.这就是著名的并发性问题. 典型的冲突有: 丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失.例如: ...
- mysql 乐观锁_使用Mysql乐观锁解决并发问题
使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...
- mysql使用条件限制乐观锁_使用Mysql乐观锁解决并发问题
使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...
- 用分布式锁解决并发问题
在系统中,当存在多个进程和线程可以改变某个共享数据时,就容易出现并发问题导致共享数据的不一致性.即多个进程同时获取到了对数据的操作权限并对数据进行了更新,很典型的场景就是在线销售系统在售卖热销商品时遇 ...
- 使用mysql悲观锁解决并发问题
使用mysql悲观锁解决并发问题 参考文章: (1)使用mysql悲观锁解决并发问题 (2)https://www.cnblogs.com/laoyeye/p/8228467.html 备忘一下.
- 分布式锁解决并发三种方案
目录 为什么使用分布式锁? 分布式锁应具备的条件 三种实现方式 1.数据库锁 1.1 乐观锁 2.基于redis的分布式锁 3.基于Zookeeper实现分布式锁 4.三种方案的比较 分布式CAP理论 ...
- mysql使用条件限制乐观锁_mysql乐观锁解决并发问题
博客2:https://www.cnblogs.com/laoyeye/p/8097684.html 1.使用版本号实现乐观锁 版本号的实现方式有两种,一个是数据版本机制,一个是时间戳机制.具体如下. ...
- 分布式锁解决并发的三种实现方式
在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务.分布式锁等.有的时候,我们需要保证一个方法在同 一时间内只能被同一个线程执行.在单机环境中,Java中其实提供了很 ...
- MySQL锁解决并发问题详解
原文地址:http://leihuang.org/2015/09/10/mysql-lock-concurrency/ 文章分为以下几个要点 问题描述以及解决过程 MySQL锁机制 数据库加锁分析 下 ...
最新文章
- MySQL数据库之-foreign key 外键(一对多、多对多、一对一)、修改表、复制表
- VC/MFC Combo Box控件的用法
- 【ZOJ - 3210】A Stack or A Queue? (模拟)
- 《编程匠艺》读书笔记之七
- 计算机基础知识187,中职计算机基础 (187)(11页)-原创力文档
- 自学linux指令分析-mkdir
- Matlab与C/C++混合编程 Matlab调用C函数
- php+mysql图书管理系统
- 计算机实验室场地报告,实验室申请报告.doc
- 【CS61A】学习笔记
- Nodejs中,使用nock做http请求的mock
- exadata的infiniband交换机的ilom
- SQL中的COALESCE()函数
- PermissionError: [Errno 13] Permission denied:报错解决
- 常用密码的正则表达式
- python-数据库-4
- 信息时代的独立阅读者(二):怎么阅读科普类文章
- 虚拟货币盘点:微币,Q币,苹果平台,Facebook 的F币,Google会推G币么?
- 抓取检测数据集Cornell数据解析
- java语言--------javaSE之内部类