NC65并发处理

所需积分/C币:50 2017-02-18 12:33:34 276KB PDF
104
收藏 收藏
举报

可以参考并使用
供应链文档 线程 线程 对加共享锁 成功 对加共享锁 成功」 调用其他服务 对加共享锁 成功 对加排它锁 失败 对加排它锁 失败 如上表所示,线程先对加共享锁成功,则线程再对加共享锁成功, 加排它锁失败,而同一个线程中调用其他服务对加排它锁失败,加共享锁成 功。加共享锁的底层调用如下:其中 是待锁定的字符串,只不过它需要 加上指定的常量 上面展示的底层的代码,我们在 层已经将其封装,如下所示 共享锁往往不会单独使用,一般都是配合排它锁一起使用,典型的使用场景 我们在后面并发控制的典型应用中描述 冂从锁的使用上考虑,分为:静态锁、动态锁 上面是从锁的互斥性上分类的,这里换一个角度考虑,既然有加锁,就需要 释放锁。那自然就有了静态锁、动态锁的概念。 静态锁加锁手工调用、释放锁也需要业务组手工写代码释放,虽然现在我 们还提供这样的机制,但在系列里几经基本上不这样做了,因为手工 释放的操作风险很大,对锁的控制需要十分精细,程序员容易犯错,并且 还需要多写代码 动态锁:这是目前正在普谝使用的锁,它的加锁同样代码主动调用,但释 放锁是动态的,当加锁所在的事务结朿后,自动释放锁,以供下次加锁使 用,这种方式即简单方便,又可避免程序员人为忘记释放锁的错误,对数 据的控制也更加严谨。我们上述代码示例都是使用的动态锁。代码示例如 选择合适的资源加锁 既然我们的加锁是对某一个字符串加锁,那到底应对什么字段加锁,这个是 由我们需要去仔细考虑的。最典型的就是锁,也就是对单据的主键加锁,由于 第页共页 供应链文档 锁住它也就唯一的锁住了这个单据或者单据的一行记录,而系统中大部分场 景都是要求单据维护操作的互斥性,所以常用在各种单据的维护操作上,比如保 存、删除、关闭、打开、审批、弃审、结算、取消结算等:而我们后台要校验唯 性的时候,比如要求同一个客户不能有某些重复的记录,那我们在校验前可能 就要对客户加锁,再例如我们在月未结账的时候往往使用成木域区隔的,我们 会在成本域加锁。 另外我们还需要考虑当发现加单据锁操作是一个效率瓶颈的时候,是不是 可以换一个角度思考,此种业务场景下对并发的要求高不高,如果对并发的要求 不高的时候,我们是不是可以牺牲一些并发性,把锁的粒度再放人些,比如加由 单据的锁换成加某一个组织的锁,也就是比如行 个加 锁,而发现其实行销售组织只有个,在不影响业务数据忙确性的 情况下是否我们可以转化为加销售组织锁,其实效率应该是有改观的。 其实说了这么多,就是想让大家明白我们在什么资源上加锁,是要经过仔细 斟酌的,不是想当然的就对某一个字符串去加锁 校验时间戳 前闻一直在说加锁,加锁控制住了资源被冋时修改的风险,但如何来保证我 们在内存屮读取到的待修改使用的数据和数据库屮对应的数据是一致的呢?这就 引出了时间戳的概念。时间戳在系统中统一使用,每张表都会默认加上时间 戳这个字段,凡是在数据库中的 操作都会更新时间戳字段,即记录数据最 后一次被修改的时间。 我们为了保证当前内存中的数据和数据库中的数据一致,往往会在使用内存 中数据之前,先査一遍当前数据库中对应数据的时间戳,俩个时间戳做比较,如 果相等,说明内存中的数据是最新的是正确的,如果不一致则说明内存中的数据 其实在数据库中已经被修改过了,已经不是最新的了,我们不能再使用。典型的 代码调用如下: 主子表: 视图 单表 加锁和校验时间戳的配合使用 作为完整的并发控制方案,需要加锁和校验时间戳同时使用,那是先加锁还 是先校验时间戳呢?加锁一般放在方法的什么位置呢?来看如下图示: 第页共页 供应链文档 查峋校验 事务执行第步,没有问题,第步还没有开始, 此时事务执行完第步也没有问题,执行第步, 由于事务还没有执行第步加锁,所以事务第 加锁成功,并且紧接着执行完第步,锁释放, 此时事务才进入第步进行加锁,由于事务已 加锁 经释放锁事务加锁成功,接着开始第步处理数 据,但此时的数据已经不被事务修改过了,已经 不是最新的了,事务再继续操作,必然发生错误, 数据处理修改 所以代码处理错误 这样的处理顺序也就没有了上述的问题,首先加锁, 加锁 不允许多个事务同时修改同一个资源,其次再校验 时间戳,保证数据与数据库中的一致性,这样就不 在会出现问题了。人家可以自行分析看看左边的示 意图是否还有缺陷。 查询校验 数据处理修改 总结一下,如果在方法的最开始就有我们可以加锁的资源,我们应该亳不犹 豫首先加锁,再去校验和处理数据。目前单据的保存、删除、审批、弃审、回 写等标准操作已经在 代码层对加锁、校验时间戳进行了封裝,所以我们在 这些标准操作的时候已经不需要我们再去写代码了。但我们需要知道原理,因为 些非标准化的后台操作还是需要我们自己去控制并发的。 加锁一定在 操作的前面,一定要记住 业务校验的重要性 我们已经有了并发控制的机制,但这里单独提醒下,重要的业务操作,对 于数据的正确性我们需要进行业务校验,即先加锁、再进行业务校验,也判读数 据正确合法性,米保证后续业务处理的正确性,此类操作多为各种结算,以及重 要的回写处理等。 第页共页 供应链文档 并发控制的典型应用场景 单据的修改保存、删除、审批、弁审 此类操作的并发控制已在如下代码中封装 □单据的回写处理 单据生成下游单据后,单据回写上游单据的萘计数量时,需要做并 发控制,以确保单据没冇被删除或者弃审。此过程是在上游亢成的,代码封裝 调用如下: 手工处理的场景 由于一些场景需要手工加锁、校验,比如结算、暂估等,那么就需要手工 调用处理可参考如下类: 主子表: 视图 单表 口后台服务接口场景 此时我们没有前台的 般不需要校验,如果入口参数有待加锁的 数据,可以直接用 对加锁,如果没有待加锁的数据,我们一般需要查询出待处理的数据,加 锁,然后再把这些当做查询条件再次査询待处理的数据,然后在对业务数据进 行数据校验,满足业务处理要求的,进行业务处理 排它锁和共享锁的综合应用场景 上面我们提到的场景都是用的排它锁,也是用到的最多的处理场景。在 供应链系统有一些记录结存数据的表,比如月结表,可用量表,信用占用量表等。 这些表都有定期计算或重算的要求,为了保证数据正确,要求在重算时,单据业 务不能同时发生,即要求重算和制单互斥。但是单据业务本身要支持并发。所以 在单据维扩时,中请加共享锁;在可用量重算时,申请加排它锁。如下图所示: 第页共页 供应链文档 订单保存 信用重算 订单对加排它锁 信用对加排它锁 订单数据处理 信用对加共享锁 信用重算处理 信用数据处理 在此图中我们可以看到,在重算过程全程加排他锁,保证重算过程没有别的 事务并发:在订单保存时对订单加排它锁保正订单数据的咔确性,订单保存时的 信用处理加共享锁,如果申请到共享锁,表明没有重算过程,订单可以保存。并 且由丁订单保存时的信用处理申请的是共享锁,所以其他订单仍然可以继续申请 该资源垬享锁,这样两张订单可以提交保存,提高了单据并发处理的能力。重算 过程只能申请到排他锁,才能重算;同时,如果有单据维护申请共享锁,将不能 成功,这样保证在重算过程中没有其他事务插入。这里注意订单自身对加锁而 信用相关处理无论是在订单保存或者重算过程中是对加锁,这都是相关的业务 和设计决定的,比如保证单据的互斥为单据锁,保证某一信用维度上数据 的正确性,为客户产品线其他维度锁。 总结 口凡是后台有数据库 的地方都应该想到并发控制问题。 □在后台校验唯一性的时候,要考虑并发问题 凡是并发控制的处理,加锁一定在业务处理的最前面。 冂当有前台数据传入的场景,加锁后一定有校时间戳这一步。 如果只是后台的服务 入口参数有加锁数据,我们先加锁再査询出待业务处理的薮据,往下处理 入口参数没有待加锁的数据,我们要先査询出待加锁的资源,然后再加锁, 最后再根据加锁的资源(一般为单据),做为査询条件,査询岀待处理 的数据,做业务校验,做业务处理 □锁的选择是根据业务设计的综合考虑,并不是单纯的单据锁 锁依然是我们最常用到的锁 第页共页

...展开详情
试读 7P NC65并发处理
立即下载 低至0.43元/次 身份认证VIP会员低至7折
一个资源只可评论一次,评论内容不能少于5个字
您会向同学/朋友/同事推荐我们的CSDN下载吗?
谢谢参与!您的真实评价是我们改进的动力~
关注 私信
上传资源赚钱or赚积分
最新推荐
NC65并发处理 50积分/C币 立即下载
1/7
NC65并发处理第1页
NC65并发处理第2页

试读结束, 可继续读1页

50积分/C币 立即下载