一、引言

  随着业务量的增加,单机部署已经无法满足日常需求了,我们可能会把代码部署到多台服务器上去来进行服务的扩容,也就是负载均衡,那在这种场景下,怎么能实现锁的概念呢?

  那么我们知道如果是一台主机部署的话,我们有很多方式可以实现锁的概念,比如利用synchronized关键字实现同步,或者使用reentrantLock可重入锁来在需要同步的场景,因为内存都是在一台机器上,可以很容易的实现对共享资源的锁定,但是多主机部署时,如果我们要锁定一个共享资源,显然这种方式无法满足我们的需求了,因为多主机部署时,我们每个主机要读取共享资源,可能会存在先后的顺序,那么在同时操纵一个数据时,就可能会存在一些很严重的问题了。

二、举个栗子

  场景:2个用户同时对一个商品进行下单,商品库存只剩下1个,服务端会进行库存扣减。

  期望结果:1个用户能下单成功,另一个用户提示库存不足

  可能存在的问题:主机1和主机2同时去读取一个商品的库存,都发现是1,然后都进行了库存扣减,扣减完成后主机1进行了提交,库存被修改为0,这个时候主机2再进行提交,库存再次减1变为-1,那不就凉凉了么?

  解决方案:数据库锁,分布式锁等(这篇文章只讨论数据库层面做的锁,分布式锁可以戳这里~

三、代码实现

  场景:商品库存为0 ,而此时进来了一个用户的购买线程

方式一 :update语句的原子性(行锁特性)实现乐观锁

  乐观锁:乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测

-- 3、对商品id为1的商品进行库存扣减
UPDATE T_GDS_INFO
SET GDS_STOCK = GDS_STOCK - 1
WHERE
GDS_ID = 1
AND GDS_ID IN (
-- 2、这里要再封装一个结果集给外层的update语句进行条件过滤,否则一条语句直接操作同一张表,即进行select又进行update会报错
SELECT
A.GDS_ID
FROM
(
-- 1、查询库存大于等于1的商品(带入需要扣减库存的商品id)
SELECT
GDS_ID
FROM
T_GDS_INFO
WHERE
GDS_ID = 1
AND GDS_STOCK >= 1
) A
);

    上面的sql可能看着这比较绕,我们来一波简易的版本:

-- 1、当库存大于等于1时才进行库存扣减
UPDATE T_GDS_INFO
SET GDS_STOCK = GDS_STOCK - 1
WHERE
GDS_ID = 1
AND GDS_STOCK >= 1

方式二 :利用版本号实现乐观锁

  思路:表里增加一个版本号的字段进行控制,每次成功更新版本号增加1,当需要进行更新操作时,先查询出版本号,然后再把查询出来的版本号作为update语句的条件带入,此时如果多个线程请求同一条数据时,查询到的版本号虽然一致,但是只有第一个提交的线程能更新成功。

-- 1、查询商品信息 得到版本号
SELECT * FROM T_GDS_INFO;
-- 2、在语句里带入查询到的版本号,每次成功更新版本号+1
UPDATE T_GDS_INFO
SET GDS_STOCK = GDS_STOCK - 1,
VERSION = VERSION + 1
WHERE
GDS_ID = 1
AND VERSION = 1
-- 3、如果同时2个订购都读取到版本号是1,然后进行库存扣减,那么第一条UPDATE语句会成功,把版本号增加变成2,而第二条UPDATE语句带入条件的版本号还是1,则会更新失败

  PS:类似的还有用时间戳字段来进行版本控制的,思路类似,这里就不进行详细说明了

Oracle学习(十七)数据库锁在分布式系统里的应用(老板,乐观锁了解一下?~)的更多相关文章

  1. 重新学习MySQL数据库10:MySQL里的那些日志们

    重新学习MySQL数据库10:MySQL里的那些日志们 同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志, ...

  2. oracle学习 十 数据库的语句优化(持续更)

    平时关注Oracle数据库的网友都知道,Oracle性能优化保证了Oracle数据库的健壮性.下面就此提出需要注意的两个原则.   原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的 ...

  3. oracle学习之数据库数据保存成文件

    常常需要将数据库中的数据生成文档,由于比较喜欢脚本的方式,所以就需要使用spool的时候进行格式设置,以下简单整理了一下oracle中进行格式设置的一些东西,一共十八条,其实常用的也就那么几个,稍后会 ...

  4. Oracle学习笔记—数据库,实例,表空间,用户、表之间的关系

    之前一直使用的关系型数据库是Mysql,而新公司使用Oracle,所以最近从网上搜集了一些资料,整理到这里,如果有不对的地方,欢迎大家讨论. 基本概念: 数据库:Oracle 数据库是数据的物理存储. ...

  5. 重新学习MySQL数据库6:浅谈MySQL的中事务与锁

    『浅入深出』MySQL 中事务的实现 在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇 ...

  6. Oracle数据库悲观锁与乐观锁详解

    数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...

  7. web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)

    这篇文章讲了 1.同步异步概念(消去很多疑惑),同步就是一件事一件事的做:sychronized就是保证线程一个一个的执行. 2.我们需要明白,锁机制有两个层面,一种是代码层次上的,如Java中的同步 ...

  8. 数据库乐观锁和悲观锁的理解和实现(转载&总结)

    数据的锁定分为两种,第一种叫作悲观锁,第二种叫作乐观锁. 1.悲观锁,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.[数据锁定:数据将暂时不会 ...

  9. Oracle的悲观锁和乐观锁

    为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...

随机推荐

  1. Linux命令大纲

    LINUX服务器,广泛用于服务器的操作系统.本文以centos作为基础大概记录下自己的心得. 一.文件/目录的增删改查 1.增加 touch filename > filename mkdir ...

  2. Shell编程—创建函数

    1基本的脚本函数 函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用.要在脚本中使用该代码块时,只要使用所起的函数名就行了. 1.1创建函数 有两种格式可以用来在bash shell脚本中创建 ...

  3. 滴滴AI Labs斩获国际机器翻译大赛中译英方向世界第三

    桔妹导读:深耕人工智能领域,致力于探索AI让出行更美好的滴滴AI Labs再次斩获国际大奖,这次获奖的项目是什么呢?一起来看看详细报道吧! 近日,由国际计算语言学协会ACL(The Associati ...

  4. Java中的 "==" 和 "equals" 区别

    分析 "==" 和 "equals" 区别的时候先了解一下Java的内存. Java内存 “==” 和  “equals” 区别” “==”: “==”比较的是 ...

  5. Android Weekly Notes Issue #428

    Android Weekly Issue #428 Kotlin Flow Retry Operator with Exponential Backoff Delay 这是讲协程Flow系列文章中的一 ...

  6. 无法登陆网站,nginx漏配置

    location / {         try_files $uri $uri/ /index.php?$query_string; }   这条主要是将index.php入口文件重写掉,所以平常我 ...

  7. 万字长文,一篇文章带你入门Python

    注释 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家提供 ...

  8. 表格取消全选框,用文字表示--Echarts ElementUi

    1.先看看实现的图 一. 添加添加复选框列 <el-table v-loading="zongShipLoading" tooltip-effect="dark&q ...

  9. PageObject六大原则

    The public methods represent the services that the page offers 公共方法表示页面提供的服务 Try not to expose the i ...

  10. Oracle 回滚段undo

    Undo的作用 数据的回滚 一致性读 表的闪回(事务,查询的闪回..) 失败会话的恢复 回滚rollback操作 SQL> archive log list; ORA-01031: 权限不足 S ...