乐观锁原理与实战演练

一、 前言

最近在做一个简单审批流程的项目,由于只有固定二级审批所以没有使用集团工作流bpms,然后就遇到一个审批节点捞单时候,多个人同时审批时候如何保证业务正常运行的问题,我采用的就是乐观锁来解决的。所谓捞单就是一个审批节点可以同时由多个人同时审批。

二、 乐观锁实现方式

乐观锁意思是说多个事务修改数据库中同一条记录时候,并不是在一个事务中使用 for update 锁定这条记录从而防止其他事务在本事务提交前访问这条记录,而是在具体执行更新语句时候进行判断,并通过更新结果影响的行数来判断当前更新是否有效。具体来说有两种实现方式:

2.1 使用业务状态来实现乐观锁

比如一个任务表里面包含如下字段:

idcommentstatus
1123456new

一个任务的status有:new,operator,manager状态。new状态下有多个A人可以去更新这条记录的comment并且把status更新为operator,但是只能有一个人能成功。operator状态下可以多个B人去更新这题记录的comment并且status更新为manager但是只有一个人能更新成功。

这时候就可以使用status这个字段的值来实现乐观锁,具体来说:‘,status=’operator’ where status = ‘new’ and id = 1;
对应B类型来说更新使用: update 表 set comment=’
‘,status=’manager’ where status = ‘operator’ and id = 1;

假如多个A类人同时去更新数据时候,第一个执行更新语句的人会锁住该条记录,更新status=’operator”,这时候其他事务是访问不了该记录的,直到当前事务提交返回结果1。当前事务提交后,然后其他事务在执行这条语句,这时候由于根据条件status = ‘new’ and id = 1获取到0条记录,所以返回0.所以如果更新结果返回1,则提示当前A类人数据更新成功,返回0的操作人则提示当前任务已经被捞单人员处理过了,无须在处理。同理B类人也是这样。

2.2 使用版本来实现乐观锁

相比于2.1 要在任务表添加一个字段version,因为并不是所有业务场景都会有一个状态枚举值来做乐观控制

idcommentstatusversion
1123456new1

如图初始化版本号为1,这时候:‘,status=’operator’,version=version+1 where version = 1 and id = 1;
对应B类型来说更新使用: update 表 set comment=’
‘,status=’manager’,version=version+1 where version = 2 and id = 1;

三、 实战演练

3.1场景介绍

  • 概念模型

0?wx_fmt=png

如图,一个合同基本信息对应多个审批任务

  • 审批流程

0?wx_fmt=png

如图三级审批,假设三级审批都是捞单角色。只有三级都审批通过后合同基本信息的状态才是审批结束,只有一个审批节点的人审批驳回后,合同基本信息状态才是驳回状态,只有申请人撤回了申请,当前状态才是撤回。其他状态下都是审批中状态,也就是说即使一级,二级审批通过了,当前合同基本信息状态是审批中状态。

所以由于一级二级审批时候当前状态都是审批中,所以没办法用2.1的方式,所以使用version的方式。

  • 问题与解决

问题一0?wx_fmt=png

考虑A和B都看到了同一个审批任务,其中A单击了审批按钮,进入了审批页面,并且审批了该任务A任务状态从new->done,取消了其他捞单任务B的任务状态new->cancel。但是此时B的审批列表里面该任务还是处于审批状态,因为他没有刷新页面,假如这时候B单击审批时候如果不做任何处理将会出现问题,所以在进入审批页面时候还需要再次校验下B的任务当前状态是否还是new。

下面在说下A和B同时进入审批页面后,A审批后,那么B在审批如何正常处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kafka是一种分布式流处理平台,它以高吞吐量、低延迟的方式传输和存储数据。Kafka的核心原理是基于发布/订阅模型,采用了一种分布式的、分区的和复制的机制来处理数据流。 Kafka的架构包括生产者、消费者、主题和分区。生产者负责将数据发布到Kafka主题,而消费者则可以通过订阅的方式从主题中读取数据。主题是数据流的逻辑单位,而分区则是主题物理上划分的部分。每个分区在存储层面上都有多个副本,以实现高可用性和容错能力。 Kafka的数据存储采用了一种顺序存储的方式,即生产者将数据追加到分区的末尾,而消费者则可以根据自己的需求从任意位置开始读取数据。这种设计使得Kafka能够实现高吞吐量的消息传输和低延迟的数据消费。 在实际应用中,可以通过Kafka进行实时数据流处理、日志收集、消息系统等场景。通过使用Kafka的复制机制,可以保证数据的可靠性和高可用性。此外,Kafka还提供了丰富的API和工具,使得开发人员可以方便地进行数据的生产和消费。 在实战演练方面,可以通过以下步骤进行: 1. 配置Kafka集群:在多台机器上安装和配置Kafka,使得它们可以组成一个集群。需要设置好主题和分区的相关参数,以满足实际需求。 2. 生产者开发:编写生产者代码,用于产生数据并将其发布到Kafka的主题中。可以设置生产者的参数,如数据的压缩方式、发送策略等。 3. 消费者开发:编写消费者代码,用于从Kafka的主题中读取数据并进行相应的处理。可以根据需求设置消费者的参数,如消费数据的位置、分区的分配等。 4. 测试数据传输:启动生产者和消费者,在Kafka集群上测试数据的传输和处理效果。可以使用Kafka的监控工具来查看集群的状态、吞吐量等指标。 总结来说,Kafka的原理是基于发布/订阅模型和分布式存储机制的,通过顺序存储和复制保证了高吞吐量和数据的可靠性。在实战演练中,需要配置Kafka集群,并编写生产者和消费者代码来进行数据的传输和处理。这些步骤可以帮助我们更好地理解和应用Kafka。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值