乐观锁

为什么需要采用乐观锁?

由于activiti一个周期的transaction时间可能比较长,且同一流程实例中存在任务并发执行等场景。设计者将update、insert、delete事务性的操作推迟至command结束时完成,这样尽量降低锁冲突的概率,由此产生基于mybatis上封装的session cache来管理这些中间状态的实体对象。但在充分竞争情况下锁是不可避免的,进一步利用乐观锁机制能保证执行模型的一致性。因为往往如果锁定相同数据记录说明多个相互影响的command并发执行,安全的策略就是让第一个命令成功,其他皆失败。

PS:

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自 外部系统的事务处理)修改持保守态度,其它事务会一直阻塞,直到这个事务结束。因此,在整个数据处理过程中,将数据处于锁定 状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能 真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修改数据)。

对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制,不会锁住任何东西。大多是基于数据版本 ( Version )记录机制实现,更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据予以驳回。

死锁

在一个command执行过程中存在开始独立的新事务PROPAGATION_REQUIRES_NEW,例如IdGenerator,DecrementJobRetriesCmd。

1、IdGenerator:为什么不用数据库序列生成器?因为此前所说我们的数据库操作全部延迟到最后执行,故而无法使用数据库的自增序列,而是采用外部序列来联系各实体。

2、DecrementJobRetriesCmd:asynchronous job执行失败,在TransactionState.ROLLED_BACK时执行job异常登记钩子

在command中嵌入开启新subcommand(该subcommand包含需获得数据库连接资源),然而在有限资源的情况下自身已经持有资源再试图去获取同类资源是相当危险的方案,由此引发的竞争往往会将你推入死锁的深渊。正如下图所示便是activiti在高并发场景下产生死锁的原因。

exclusive jobs

问题抛出

并行execution中servicetask async=true,当他们各自被不同worker thread执行,当一个execution跑到join节点会判断是否除己之外所有的income flow都已到达,如果是则走过join否则join等待。但是当多个flow同时到达join,因为此时他们各自对于对方是不可见的,都假定对方没有到达,导致都认为要等待对方,从而导致join永远不会执行。

前面所述乐观锁在并发情况下同时只会保证第一个提交的job成功,其他抛出ActivitiOptimisticLockingException失败,从而在一定的时间后重试,但重试的次数是有限的(默认为3次),并行线路越多冲突重试的可能性也越大。且如果task service不在bpm transaction控制之下(比如POST外部系统接口),则业务不能正确回滚,被执行多次。

exclusive job 保证隶属同一process instance的job是被顺序执行,即在org.activiti.engine.impl.jobexecutor.AcquireJobsRunnable中将同一流程的job压人同一批次。

activiti 为什么需要采用乐观锁?相关推荐

  1. oracle的乐观锁和悲观锁

    一.问题引出 1. 假设当当网上用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是'有效',表示该订单是有效的: 2. 后台管理人员查询到这条001的订单,并且看到状态 ...

  2. 华为应用锁退出立即锁_面试官:你说说互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景...

    前言 生活中用到的锁,用途都比较简单粗暴,上锁基本是为了防止外人进来.电动车被偷等等. 但生活中也不是没有 BUG 的,比如加锁的电动车在「广西 - 窃·格瓦拉」面前,锁就是形同虚设,只要他愿意,他就 ...

  3. java oracle 乐观锁,oracle为什么默认乐观锁

    本帖最后由 bfc99 于 2015-7-6 11:08 编辑 1.无论是选择悲观锁策略,还是乐观锁策略.如果一个对象被上了锁,那么该对象都会受这个锁的控制和影响.如果这个锁是个排它锁,那么其它会话都 ...

  4. 关抢占 自旋锁_互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景

    前言 生活中用到的锁,用途都比较简单粗暴,上锁基本是为了防止外人进来.电动车被偷等等. 但生活中也不是没有 BUG 的,比如加锁的电动车在「广西 - 窃·格瓦拉」面前,锁就是形同虚设,只要他愿意,他就 ...

  5. 面试官:你说说互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景?

    前言 生活中用到的锁,用途都比较简单粗暴,上锁基本是为了防止外人进来.电动车被偷等等. 但生活中也不是没有 BUG 的,比如加锁的电动车在「广西 - 窃·格瓦拉」面前,锁就是形同虚设,只要他愿意,他就 ...

  6. 乐观锁 与 悲观锁 总结

    悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁.传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等 ...

  7. 悲观锁、乐观锁以及分布式锁

    1.单机应用乐观锁悲观锁,select 时怎么加排它锁? 1.1悲观锁(Pessimistic Lock): 悲观锁特点:先获取锁,再进行业务操作. 即"悲观"的认为获取锁是非常有 ...

  8. MySql事务4种隔离级别以及悲观锁和乐观锁

    前言:在那鬼公司呆着发现自己居然把事务给搞明白了. 缘由:公司做的一个项目在进行首页内容显示的时候发现查询结果特别慢,有时候需要一到五分钟才能显示出结果.于是乎,我就顺着SQL语句查询慢的原因找了下去 ...

  9. 分布式锁:互斥锁、自旋锁、读写锁、悲观锁、乐观锁

    前言 如何用好锁,也是程序员的基本素养之一了. 高并发的场景下,如果选对了合适的锁,则会大大提高系统的性能,否则性能会降低. 所以,知道各种锁的开销,以及应用场景是很有必要的. 接下来,就谈一谈常见的 ...

最新文章

  1. android 按照星期 时间 定时_Spring Boot实现定时任务的四种方式
  2. tensorflow gan 网络 示例
  3. 行业观察 | 新一轮AI周期里,华为拿什么破解核心难题?
  4. IOS开发1-动画 背景渐隐,view上移
  5. 表单如何添加大的文本框_在 Flutter 中进行文本框的创建和设定
  6. hdu 3401(单调队列优化dp)
  7. PropertiesUtil 获取文件属性值
  8. 奇安信代码安全实验室帮助谷歌修复 Chrome 沙箱外高危漏洞,获官方致谢
  9. iOS CoreData (二) 版本升级和数据库迁移
  10. 蓝牙精确定位技术下的化工厂安全管理系统,蓝牙定位标签-新导智能
  11. linux强制删除只读文件夹,强制删除文件夹linux的方法是什么
  12. 重卡自动驾驶进入“正规战”
  13. scrapy下载斗鱼主播图片
  14. 弱电布线工程实战攻略
  15. 树莓派换源 bullseye
  16. 书单|双十一必入的科普口碑好书
  17. [转]个性化推荐--能否造就下一代霸主?
  18. 一位计算机硕士毕业生三个月求职经历与经验的结晶
  19. python使用matplotlib绘制鼠标路径
  20. 关于servlet生命周期

热门文章

  1. leetcode 滑动窗口小结 (三)
  2. Java RandomAccessFile readInt()方法与示例
  3. 用于将类型从double转换为int的C#程序
  4. librtmp分析(接收数据包处理)
  5. c和汇编混合编程----shellcode----弹出计算器
  6. matlab figure 嵌套,操作Matlab的Figure窗口(一)
  7. idea代码样式模板_阿里p3c(代码规范,eclipse插件、模版,idea插件)
  8. Ubuntu14.04设置开机可以以root用户身份登录
  9. c 语言读取注册表信息,C++读取注册表的实现方法
  10. UVA 10588—— Queuing at the doctors