数据库锁解决并发问题

问题描述: 一个优惠券活动,用户可以领取优惠券,但是一个优惠券活动领取数量有限制,所以用户在领取的时候就需要先统计一下以领用的优惠券数量。 然后在生成这张优惠券领取记录。那么此时就会出现并发问题,当多个用户领取同一个优惠券活动的时候,他们统计的优惠券已领数量小于限定可领取数量,所以都可以执行生成 优惠券领取记录的操作,但是剩下的可领取数量可能小于这些用户数量。

如何来解决这个问题呢,首先我们会想到,在程序中使用synchronized关键字来锁住领取优惠券的方法,那么就可以实现,当一个人在领取优惠券的时候其他人等待,但是程序 都是分发到多台服务器的,在分布式的情况下,这种方法并没有效果,因为程序中所能做到的只是锁住单台服务器上面的操作。

既然程序中无法实现,那么我们就想到利用数据库来实现,因为我现在做的这个项目,数据库是没用从库的,只有一台数据库服务器,如果数据库也分布式了,那就要另求它法了。

想到用数据库解决后,首先想到的是利用事务的原子性来解决,就是统计已领用数量的操作和生成优惠券记录的操作合成为一个事务,表面上感觉可以了,但其实这样做也是错误的。 因为多个事务同时处理时,情况也是一样的,同样会出现并发问题。

所以单单利用事务还是不行的,还必须使用数据库的锁机制。

InnoDB实现了以下两种类型的行锁。

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁(可以读不能写)。

  • 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁(不能读也不能写)。

锁的范围:行锁: 对某行记录加上锁 ; 表锁: 对整个表加上锁

此处我们需要使用的是排它锁,就是当一个事物在进行操作的时候,其他事物不能去统计已经领取优惠券的数量,只有领取完成之后才能统计。锁的范围是行。

使用排他锁的方法其实是悲观锁机制,我们还有乐观锁,接下来就先介绍下二者区别。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。 悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

乐观锁不能解决脏读的问题。 乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。 可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时, 数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。

如果使用乐观锁的方式,我们就需要给数据库有当前优惠券活动已领取数量的字段,每次我们修改这个字段的值时对其就行判断,如果他小于可领取数量,那么久可以插入 这条优惠券记录。这样判断和更新是在同一条sql中,这样就利用一条sql的原子性,避免并发冲突。

reference:

  • MySQL中SELECT+UPDATE处理并发更新问题解决方案

  • 事务处理和锁定语句

posted on 2017-03-06 20:20 林中侠客 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/luojianqun/p/6511734.html

数据库锁解决并发问题相关推荐

  1. 乐观锁与悲观锁——解决并发问题

    引言   在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突.这就是著名的并发性问题. 典型的冲突有: 丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失.例如: ...

  2. mysql 乐观锁_使用Mysql乐观锁解决并发问题

    使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...

  3. mysql使用条件限制乐观锁_使用Mysql乐观锁解决并发问题

    使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...

  4. 用分布式锁解决并发问题

    在系统中,当存在多个进程和线程可以改变某个共享数据时,就容易出现并发问题导致共享数据的不一致性.即多个进程同时获取到了对数据的操作权限并对数据进行了更新,很典型的场景就是在线销售系统在售卖热销商品时遇 ...

  5. 使用mysql悲观锁解决并发问题

    使用mysql悲观锁解决并发问题 参考文章: (1)使用mysql悲观锁解决并发问题 (2)https://www.cnblogs.com/laoyeye/p/8228467.html 备忘一下.

  6. 分布式锁解决并发三种方案

    目录 为什么使用分布式锁? 分布式锁应具备的条件 三种实现方式 1.数据库锁 1.1 乐观锁 2.基于redis的分布式锁 3.基于Zookeeper实现分布式锁 4.三种方案的比较 分布式CAP理论 ...

  7. mysql使用条件限制乐观锁_mysql乐观锁解决并发问题

    博客2:https://www.cnblogs.com/laoyeye/p/8097684.html 1.使用版本号实现乐观锁 版本号的实现方式有两种,一个是数据版本机制,一个是时间戳机制.具体如下. ...

  8. 分布式锁解决并发的三种实现方式

    在很多场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务.分布式锁等.有的时候,我们需要保证一个方法在同 一时间内只能被同一个线程执行.在单机环境中,Java中其实提供了很 ...

  9. MySQL锁解决并发问题详解

    原文地址:http://leihuang.org/2015/09/10/mysql-lock-concurrency/ 文章分为以下几个要点 问题描述以及解决过程 MySQL锁机制 数据库加锁分析 下 ...

最新文章

  1. mysql 的 VARCHAR VARCHAR2
  2. BC之链式块状结构:区块链之链式块状结构——链式块状结构、内容相关配图
  3. 【转】jQuery.ajax向后台传递数组问题
  4. V神演讲干货全送上!关于以太坊2.0,你想知道的都在这里!
  5. telnet怎么算成功_有机肥发酵剂有的作用,怎么才算发酵成功?
  6. 拯救天使 (BFS)
  7. 什么是顶级域名,二级域名和三级域名
  8. 无线路由器桥接——手机连不上网
  9. GAMMA初学笔记一
  10. 迅雷启动慢 解决方法
  11. [Hadoop in China 2011] 人人网:基于Hadoop的SNS统计和聚类推荐
  12. 本地颁发 SSL 证书,并开启 https 服务调试
  13. [转]平凡是福,金玉满堂,莫之能守。富贵而骄,自遗其咎。
  14. nodejs+vue 蛋糕甜品商城系统
  15. PMP第四章:项目整合管理
  16. python从键盘输入一个数、判断其是奇数还是偶数_从键盘上任意输入一个正数,判断是奇数还是偶数...
  17. USB接口测试器--USB2.0/USB3.0信号检测器
  18. 第1回 V模型,我的完整诠释
  19. 感恩美文:生命中总有一些人值得感恩
  20. 【算法练习】字符串处理 poj2690:首字母大写

热门文章

  1. ARC与非ARC混编
  2. MFC控件的SubclassDlgItem
  3. java mac postgresql_Mac上安装配置和简单使用PostgreSQL(仍然很不懂)
  4. button点击改变颜色_【干货】眉笔颜色要选对,三步教你选择正确眉色
  5. DSP集成开发工具CCS的Git工具使用说明(一)
  6. java uml 为什么_Java开发为什么需要UML
  7. window python输入路径问题--转义字符
  8. Nginx安装及运行服务
  9. String 中的hashCode方法
  10. Django REST framework API 指南(25):状态码