Oracle学习(十七)数据库锁在分布式系统里的应用(老板,乐观锁了解一下?~)
一、引言
随着业务量的增加,单机部署已经无法满足日常需求了,我们可能会把代码部署到多台服务器上去来进行服务的扩容,也就是负载均衡,那在这种场景下,怎么能实现锁的概念呢?
那么我们知道如果是一台主机部署的话,我们有很多方式可以实现锁的概念,比如利用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学习(十七)数据库锁在分布式系统里的应用(老板,乐观锁了解一下?~)的更多相关文章
- 重新学习MySQL数据库10:MySQL里的那些日志们
重新学习MySQL数据库10:MySQL里的那些日志们 同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志, ...
- oracle学习 十 数据库的语句优化(持续更)
平时关注Oracle数据库的网友都知道,Oracle性能优化保证了Oracle数据库的健壮性.下面就此提出需要注意的两个原则. 原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的 ...
- oracle学习之数据库数据保存成文件
常常需要将数据库中的数据生成文档,由于比较喜欢脚本的方式,所以就需要使用spool的时候进行格式设置,以下简单整理了一下oracle中进行格式设置的一些东西,一共十八条,其实常用的也就那么几个,稍后会 ...
- Oracle学习笔记—数据库,实例,表空间,用户、表之间的关系
之前一直使用的关系型数据库是Mysql,而新公司使用Oracle,所以最近从网上搜集了一些资料,整理到这里,如果有不对的地方,欢迎大家讨论. 基本概念: 数据库:Oracle 数据库是数据的物理存储. ...
- 重新学习MySQL数据库6:浅谈MySQL的中事务与锁
『浅入深出』MySQL 中事务的实现 在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇 ...
- Oracle数据库悲观锁与乐观锁详解
数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...
- web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)
这篇文章讲了 1.同步异步概念(消去很多疑惑),同步就是一件事一件事的做:sychronized就是保证线程一个一个的执行. 2.我们需要明白,锁机制有两个层面,一种是代码层次上的,如Java中的同步 ...
- 数据库乐观锁和悲观锁的理解和实现(转载&总结)
数据的锁定分为两种,第一种叫作悲观锁,第二种叫作乐观锁. 1.悲观锁,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.[数据锁定:数据将暂时不会 ...
- Oracle的悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...
随机推荐
- golang目录
基础 golang安装及vscode编辑器配置 golang基础结构 golang基础数据类型 golang复合数据结构 goalng函数 golang方法 golang接口 golang并发 gol ...
- springMVC入门(七)------RESTFul风格的支持
简介 RESTful风格(Representational State Transfer),又叫表现层状态转移,是一种开发理念,也是对HTTP协议很好的诠释 主要理念是将互联网中的网页.数据.服务都视 ...
- Docker Run Cadvisor failed: inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: no such file or directory
原文链接:https://blog.csdn.net/poem_2010/article/details/84836816 没有找这个文件, 这是一个bug,在系统中,是cpu,cpuacct 可以去 ...
- PowerDesigner 使用笔记
1.将mysql数据结构导入到PowerDesigner https://blog.csdn.net/guochanof/article/details/81905616 2.设计数据库过程 http ...
- Protocol buffers--python 实践 简介以及安装与使用
简介: Protocol Buffers以下简称pb,是google开发的一个可以序列化 反序列化object的数据交换格式,类似于xml,但是比xml 更轻,更快,更简单.而且以上的重点突出一个跨平 ...
- 牛客网PAT练兵场-统计同成绩学生
题解:开100的数组,进行存储人数,方便查询 题目地址:https://www.nowcoder.com/questionTerminal/3df4810cc0664b8bb848d785f68f7c ...
- 万字长文,Python数据分析实战,使用Pandas进行数据分析
文章目录 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大家 ...
- Apache Pulsar 社区周报:08-15 ~ 08-21
关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息.存储.轻量化函数式计算为一体,采用计算与存储分离架构设计,支 ...
- asp image
@Url.Content("~/Content/images/myimage.png") <img src="~/Content/images/myimage.pn ...
- [BUUOJ记录] [ACTF2020 新生赛]BackupFile、Exec
两道题都比较简单,所以放到一块记下来吧,不是水博客,师傅们轻点打 BackupFile 题目提示“Try to find out source file!”,访问备份文件/index.php.bak获 ...