当前位置: 首页 > news >正文

m2型虚拟主机带宽 网站汕头搭建建站

m2型虚拟主机带宽 网站,汕头搭建建站,如何设计软件界面,网页设计布局分析1. 问题背景 问题发生在快递分拣的流程中#xff0c;我尽可能将业务背景简化#xff0c;让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务#xff0c;我们称它为 task。task 中有两个字段需要关注#xff0c;一个是分拣中发生的异常#xff08;exp…1. 问题背景 问题发生在快递分拣的流程中我尽可能将业务背景简化让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务我们称它为 task。task 中有两个字段需要关注一个是分拣中发生的异常exp_type另一个是分拣任务的状态status。另外需要关注分拣状态上报接口通过它来记录分拣过程中的异常和状态变更。 一般情况下分拣机在分拣异常发生时会及时调用接口上报在分拣完成时调用接口来标记为完成状态两次接口调用的时间间隔较长不会发生并发问题。 但是有一种特殊的分拣机它不会在异常发生时及时上报而是在分拣完成时将分拣过程中发生的异常和分拣结果一起上报那么此时分拣状态上报接口在同一时间内就会有两次调用这时便发生了预期外的并发问题。 我们先看下分拣状态上报接口的执行流程 先查询到该分拣任务 task默认情况下 exp_type 和 status 均为默认值0分拣异常修改 task 中的 exp_type分拣完成修改 status 字段信息修改完成将 task 写入 并发问题发生的图示如下 数据库初始值为1, 0, 0分拣异常和分拣完成几乎同时上报它们都读取到该值。分拣异常动作将 exp_type 修改为9写入数据库此时数据库值为1, 9, 0分拣完成动作将 status 修改为1写入数据库使得数据库最终值为1, 0, 1它将异常字段的值覆盖掉了。正常情况下最终值应该为1, 9, 1分拣完成动作应该读取到分拣异常完成后的值1, 9, 0后再进行修改才对。 2. 解决方案 发生这个问题的原因很容易就能发现两个事务同时执行读取-修改-写入序列其中一个写操作在没有合并另一个写操作变更的情况下直接覆盖了另一个写操作的结果所以导致了数据的丢失。 这种问题是比较典型的丢失更新问题可以通过对数据库读操作加锁或者改变数据库的隔离级别为可串行化使事务串行执行的方式进行避免。下面我会将大家在讨论避免丢失更新问题时提出的方案进行介绍并尽可能的用代码来表现它们。 2.1 数据库读操作加锁和可串行化隔离级别 我们可以考虑如果对每条Task数据修改的事务都是在当前事务完成之后才允许后续事务进行修改使事务串行执行那么我们就能够避免这种情况。比较直接的实现是通过显式加锁来实现如下 select exp_type, status from task where id 1 for update; 先查询该行数据的事务会获取到该行数据的排他锁后续针对该数据的所有读写请求都会被阻塞直到先前事务执行完将锁释放。 这样通过加锁的方式实现了事务的串行执行。但是在为SQL添加加锁语句时需要确定是不是为该行数据加锁而不是锁住了整个表如果是后者那么可能会造成系统性能严重下降而且还需要关注有哪些业务场景使用到了该SQL是否存在长时间执行的只读事务使用如果存在的话可能会出现因加锁导致延迟和系统性能下降所以需要谨慎的评估。 此外可串行化的数据库隔离级别也能保证事务的串行执行不过它针对的是所有事务。一般情况下为了保证性能我们不会采用这种方案默认使用MySQL可重复读隔离级别。 MySQL的InnoDB引擎实现可串行化隔离级别采用的是2PL机制在第一阶段事务执行时获取锁第二阶段事务执行完成释放锁。 2.2 针对业务只修改必要字段 如果异常状态请求仅修改 exp_type 字段分拣完成仅修改 status 字段的话那么我们可以梳理一下业务逻辑仅将必要修改的字段写入数据库这样就不会发生丢失更新的异常如下代码所示 // 处理异常状态请求封装修改数据的对象 Task task new Task(); tast.setId(id); task.setExpType(expType);// 更改数据 taskService.updateById(task); 在执行修改数据前创建一个新的修改对象并只为其必要修改字段赋值。但是还需要考虑的是如果这个业务流程处理已经很复杂了很可能不清楚该为哪些字段赋值而导致再发生新的异常所以采用这种方法需要对业务足够熟悉并且在修改完后进行充分的测试。 2.3 分布式锁 分布式锁的方法与方法一类似都是通过加锁的方式来保证同时只有一个事务执行区别是方法一的锁加在了数据库层而分布式锁是借助Redis来实现。 这种实现方式的好处是锁的粒度小发生锁争抢仅限于单个包裹无需像数据库加锁一样去考虑锁的粒度和对相关业务的影响。伪代码如下所示 // 分布式锁KEY String distributedKey String.format(DISTRIBUTED_KEY_PREFIX, packageNo); try {// 分布式锁阻塞同一包裹号的修改lock(distributedKey);// 处理业务逻辑handler(); } finally {// 执行完解锁redissonDistributedLocker.unlock(distributedKey); } 需要注意lock()加锁方法要保证加锁失败或发生其他异常情况不影响业务逻辑的执行并设定好锁持有时间和等待锁的阻塞时间此外解锁方法务必添加到finally代码块中保证锁的释放。 2.4 CAS CAS是乐观的解决方案它一般通过在数据库中增加时间戳列来记录上次数据更改的时间当新的事务执行时需要比对读取时该行数据的时间戳和数据库中保存的时间戳是否一致以此来判断事务执行期间是否有其他事务修改过该行数据只有在没有发生改变的情况下才允许更新否则需要重试这个事务。样例SQL如下所示 update task set exp_type #{expType}, status #{status}, ts #{currentTs} where id #{id} and ts #{readTs} 它的原理不难理解但是实现起来可能会存在困难因为需要考虑在执行失败后该如何重试重试的方式和重试的次数需要根据业务去判断。 巨人的肩膀 《数据密集型应用系统设计》第七章 事务 作者京东物流 王奕龙 来源京东云开发者社区 自猿其说Tech 转载请注明出处
http://www.w-s-a.com/news/480058/

相关文章:

  • 攀枝花市网站建设outlook企业邮箱注册申请
  • 企业网站建设报价单免费劳务网站建设
  • 天津平台网站建设方案国际新闻最新消息今天乌克兰与俄罗斯
  • 食用油 网站 模板网页游戏网站在线玩
  • 做网站用的书新能源东莞网站建设技术支持
  • 漯河网站超市建设软件开发的五个阶段
  • 制作深圳网站建设阿里OSS做网站图库费用
  • 网页设计与网站建设 入门必练宜都网站seo
  • 网站设计沟通阆中网站网站建设
  • 缩短网址做钓鱼网站如何确保网站安全
  • 网店网站开发怎样用ps做企业网站
  • 南京门户网站建设做网站一般注册哪几类商标
  • 企业咨询管理服务wordpress seo tdk
  • 做网站前期创建文件夹flash 开发的网站
  • 天津网站制作培训搭建网站的工具
  • 江西网站建设价格低网上卖产品怎么推广
  • 做aelogo动效有什么好的网站建立网站站点的步骤
  • 无锡网站推广公司排名网站赚钱平台
  • 网站物理结构利用公共dns做网站解析
  • 苍南做网站微信建设网站哪家好
  • 华中农业大学基因编辑在线设计网站网站蓝色配色
  • 洛阳建设工程信息网站怎么在服务器建立网站
  • 陕西省建设部官方网站微信小程序怎么关闭这个功能
  • 唐河县住房和城乡建设局网站公司需要做网站
  • 体现网站特色免费个人域名网站
  • ps国外教程网站seo优化是什么职业
  • 什么是网站单页适合女生做的网站
  • 环境文化建设方案网站企业英语网站
  • 南通网站关键词推广响应式网站建设流程
  • 湖北响应式网站建设企业做漫画网站 漫画哪找