首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一锁二判三更新

一锁二判三更新

原创
作者头像
小时的棒棒糖
修改于 2023-09-21 13:21:16
修改于 2023-09-21 13:21:16
1.1K0
举报

原则一锁二判三更新四释放的原则

每年支付宝在双11和双12的活动中,都展示了绝佳的技术能力。这个能力不但体现在处理高TPS量的访问,更体现在几乎不会出错,不会出现重复支付的情况,那这个是怎么做到的呢?

诚然,为了实现在高并发下仍不会出错的技术目标,支付宝下了很多功夫,比如幂等性的处理,分布式事务的使用等等,但是个人觉得其中最关键的一点就是“一锁二判三更新”这句看似毫不起眼的口诀。

何为“一锁二判三更新”? 简单来说就是当任何一个并发请求过来的时候

  1. 我们先锁定关联单据
  2. 然后判断关联单据状态,是否之前已经更新过对应状态了
  3. 如果基于第2步判断,之前并没有请求更新过对应状态,则本次请求可以更新并完成相关业务逻辑。如果之前已经有更新过状态了,则本次不能更新,也不能完成业务逻辑。

话不多说,我们直接上代码:

代码语言:java
AI代码解释
复制
//第1步锁当前支付单
PaymentInfo resultPaymentInfo = commonPayCoreService
  .queryPaymentForUpdate(createPaymentInfo.getId());
if (resultPaymentInfo.isFinalStatus()) {
      //第2步,判断当前支付单状态,如果是终态,则直接返回
       //不做任何更新
      return resultPaymentInfo;
}
//第3步更新当前支付单状态到终态,并完成相关业务逻辑(支付成功)
 payCoreService.updateRequestResult(payChannelResult);

基于以上方案可以100%确保在并发情况下不会出现重复更新问题,按理论来说,就是每次状态机变更前,都要在并发安全情况下判断状态是否已经发生过变更了。

如果第1步或第2步缺失了,会发生什么问题,我们来看一下

只要把这3步作为我们的代码规范,则可以避免大部分的并发重复操作问题。对于异步并发重复消息的处理亦是如此,加深对状态机的判断后还可以处理消息乱序问题。

对于锁的使用可根据实际情况选择悲观锁和乐观锁。

关于悲观锁(数据库行锁),乐观锁(数据库版本锁或分布式锁)的实现方式和坑我们以后再详细说。

可能有人会问不管是悲观锁还是乐观锁对系统的并发量都是有影响的,这个怎么解决?我的观点是在现代分布式系统中,如果追求高可用和稳定则必须在方案上优先满足,对于性能可以通过优化代码逻辑,优化技术架构,扩展数据库资源等方式来解决。

在之前蚂蚁金服的压测中,我负责的结算系统内部有10次左右SQL调用以及一次远程调用(约花费100ms),总流程花费180ms左右。在一台4核8G的机器上压测,java服务并发可以达到150TPS,结果还是令人满意的,通过水平服务器扩展完全没有问题。

在整个支付宝技术架构中,只有一个场景是没有用锁和判断直接更新的,就是2016年的春节五福红包,高达上百万的TPS访问,为了保证用户的顺畅体验,牺牲了状态判断的安全性,在事后再做一次对账(虽然就算出错也于事无补了 :))

总结:

高并发,锁只是第一步(重点考虑:锁的粒度,加锁的顺序,会不会加锁抛出导致锁释放环节抛异常),

重要的是处理过程: 先查询出来结果的缓存,

判断是否是终态(幂等)

缓存没有数据再查询数据库

然后是更新,走具体业务逻辑

最后一步是释放锁

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
Oracle逻辑迁移某业务用户及数据
那么在导出开始前,需要停止源数据库业务,直到成功导入到目标数据库时,应用修改新的连接方式完毕,才可以再次启动业务;
Alfred Zhao
2019/05/24
8650
相克军_Oracle体系_随堂笔记012-undo
undo表空间中undo段是自动生成的,oracle自动使用undo表空间的undo段。
Alfred Zhao
2019/05/24
4770
Oracle数据逻辑迁移综合实战篇
本次需求: 指定用户表结构迁移,所有表需要数据(因为此用户下的数据规模是10T的级别,所以想完全迁移不现实,最终确定为大表迁移部分数据,小表迁移全部数据)。 至于大表和小表的界定,研发侧不能提供,需要DBA自行评估划分。
Alfred Zhao
2019/05/24
8920
undo retention的思考(一)
最近有个网友咨询我一个问题,是关于undo_retention的,对于这个参数没有过多关注,只是知道需要设置undo_retention搭配使用undotablespace retention guarantee 通过邮件的操作记录可以看出这个网友还是很严谨的,每一个步骤都很详细的列了出来,这位网友在测试11.2.0.1.0的环境中发现undo retention没有像期望值那样来达到预期的效果。 自己在本地测试了多次,虽然结果还是不够理想,不过基本思路已经有了,继续努力。 我所在的环境是11.2.0.4
jeanron100
2018/03/16
1.4K0
EXPDP/IMPDP更改用户 表空间 表名
1、创建directory JZH@test>create directory test_dir as '/home/oracle/'; Directory created. 2、创建测试表 JZH@test>create table emp1 as select * from scott.emp; Table created. 3、查看表所在表空间 JZH@test>select owner,table_name,tablespace_name from dba_tables where table_name='EMP1'; OWNER TABLE_NAME TABLESPACE_NAME ------------------------------ ------------------------------ ------------------------------ JZH EMP1 USERS expdp jzh/jzh dumpfile=emp1.dmp directory=test_dir tables=emp1 logfile=emp1.log Export: Release 11.2.0.3.0 - Production on Sat Sep 27 15:09:23 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options Starting "JZH"."SYS_EXPORT_TABLE_01": jzh/******** dumpfile=emp1.dmp directory=test_dir tables=emp1 logfile=emp1.log Estimate in progress using BLOCKS method... Processing object type TABLE_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 64 KB Processing object type TABLE_EXPORT/TABLE/TABLE . . exported "JZH"."EMP1" 8.562 KB 14 rows Master table "JZH"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded ****************************************************************************** Dump file set for JZH.SYS_EXPORT_TABLE_01 is: /home/oracle/emp1.dmp Job "JZH"."SYS_EXPORT_TABLE_01" successfully completed at 15:09:40 4、查询emp1表 select empno,ename,sal,comm from emp1; EMPNO ENAME SAL COMM ---------- ---------- ---------- ---------- 7369 SMITH 1900 7499 ALLEN 1600 300 7521 WARD 1250 500 7566 JONES 2975 7654 MARTIN 1250 1400 7698 BLAKE 2850 7782 CLARK 2450 7788 SCOTT 3000
用户5640963
2019/07/26
2.1K0
【迁移】Oracle分区表及索引迁移表空间
近期计划使用XTTS方式迁移某库,在进行自包含检查时发现,该库有部分数据(分区表、索引)存放于SYSTEM表空间中,需要先将这部分数据移动到要迁移的表空间中。
甚至熊熊
2021/04/22
2.7K0
expdp和impdp的实践
导入导出我们经常用的是exp/imp命令,确实比较方便,但也有局限,例如需要导入导出的表空间名相同、schema名需要相同。
bisal
2019/01/29
8600
XTTS系列之一:U2L迁移解决方案之XTTS的使用
本系列的定位是对XTTS及相关技术进行深入的学习研究。作为本系列的开篇,本着实用性的原则,我先把一次实际生产环境U2L的迁移实战实施方案进行提炼简化,旨在能清楚说明该如何使用XTTS这种解决方案来进行U2L迁移,先达到可以跟着做下来的初级目标,如果有兴趣再去深入研究相关细节。
Alfred Zhao
2019/07/29
2.4K0
expdp|impdp及exp|imp指令介绍
expdp介绍 EXPDP命令行选项 1. ATTACH 该选项用于在客户会话与已存在导出作用之间建立关联.语法如下 ATTACH=[schema_name.]job_name Schema_name用于指定方案名,job_name用于指定导出作业名.注意,如果使用ATTACH选项,在命令行除了连接字符串和ATTACH选项外,不能指定任何其他选项,示例如下: Expdp scott/tiger ATTACH=scott.export_job 2. CONTENT 该选项用于指定要导出的内容.默认值为ALL
用户1257215
2018/01/30
2.7K0
expdp|impdp及exp|imp指令介绍
Oracle-数据泵expdp/impdp实操
因数据库版本为11.2(大于Oracle10g)初步确定使用数据泵的方式从198导出后导入197数据库
小小工匠
2021/08/16
1.3K0
oracle常用命令大全
一、Oracle数据库实例、用户、目录及session会话查看: 1、ORACLE SID查看设置 查看SID、用户名 $ env|grep SID 、select * from v$instance、select instance_name,host_name from v$instance; 查看数据库所有用户及用户状态: SQL> select usernames,account_status from dba_users; 设置SID $ export ORACLE_SID=hisvhfs 查看数据
企鹅号小编
2018/02/02
2.8K0
数据泵IMPDP 导入工具的使用
数据的导入导出时数据库经常处理的作业之一,Oracle 提供了IMP和IMPDP以及SQL*Loader等工具来完成数据的导入工作,其中IMP服务于早期的9i之前的版本,在10g及后续版本,Oracle 提供了数据泵高速导入工具,本文主要介绍IMPDP的使用方法,关于高速导出工具请参照:数据泵EXPDP 导出工具的使用。SQL*Loader请参照:SQL*Loader使用方法。
Leshami
2018/08/07
1.6K0
一线运维 DBA 五年经验常用 SQL 大全(二)
本文 SQL 及相关命令均是在运维工作中总结整理而成的,对于运维 DBA 来说可提高很大的工作效率,值得收藏。当然如果你全部能够背下来那就很牛逼了,如果不能,还是建议收藏下来慢慢看,每条 SQL 的使用频率都很高,肯定能够帮助到你。
JiekeXu之路
2021/03/15
9440
一线运维 DBA 五年经验常用 SQL 大全(二)
Oracle 回滚(ROLLBACK)和撤销(UNDO)
Oracle使用数据库中的回滚段来实现未提交数据或因系统故障导致实例崩溃时进行回滚操作
Leshami
2018/08/07
2.5K0
Oracle架构设计
Oracle数据库的表空间管理可以说是非常简单和基础的一项维护工作,但是越简单的事情就越要制定统一的规范,这样数据库的各项管理工作才会愈加的简单高效。
Alfred Zhao
2019/05/24
6660
笔记分享(1) oracle常用查询语句
以下的oracle常用查询笔记是我之前工作中用到过的. 其实常用的查询差不多就是这些.
大大刺猬
2021/04/01
1.4K0
Oracle-HWM(High Water Mark) 高水位解读
ORACLE在逻辑存储上分4个粒度 ,由大到小为: 表空间, 段, 区 和 块.
小小工匠
2021/08/16
3K0
ORA-01654错误
create index IDX_ANA_OFFICE on ANA (OFFICE_CITY, OFFICE_NO)   tablespace IDX   pctfree 10   initrans 2   maxtrans 255   storage   ( initial 128K     next 128K     minextents 1     maxextents unlimited     pctincrease 0   );
bisal
2019/01/29
1.2K0
如何删除回滚段状态为NEEDS RECOVERY的undo表空间
环境:RHEL 6.4 + Oracle 11.2.0.4 背景:备份恢复的测试库在一次不完全恢复后,没有来及做有效的全备,又一次数据库故障导致数据库无法正常open。 只能离线部分数据文件打开数据库,其中包含undo表空间数据文件。 适用场景:无有效备份,可以丢失数据,删除回滚段状态为NEEDS RECOVERY的undo表空间。
Alfred Zhao
2019/05/24
1.1K0
Oracle数据库迁移:异构传输表空间TTS HP-UX迁移至Redhat Linux 7.7
由于本次迁移为历史库迁移,且数据库未开启归档模式,所以选择较为便捷第二种方式进行迁移。
数据和云
2021/03/09
3.5K0
相关推荐
Oracle逻辑迁移某业务用户及数据
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档