• 事物隔离级别和乐观锁


      最近在迁移代码,迁移过程中发现了一段应用了乐观锁的代码(这是伪代码):

        public boolean doWork(final int count, Entity entity) throws InterruptedException {
            if (3 == count) {
                return false;
            }
            int j = dao.update(entity);
            if (j == 0) {
                Thread.sleep(100);
                count++;
                Entity entity = dao.selectEntity(entity.id);
                return doWork(count, entity);
            } 
            return true;
        }

      大概意思是先执行更新。更新对应的表有一个version字段,entity的实例中是包含当前版本号的,更新时版本号匹配则返回true;如果不匹配则去数据库查询新的版本号,如果重试达到三次则报错。其实递归次数不多本来这也没什么问题,但是问题在于这段代码在一个事务中,而事务用的是默认的隔离级别,关键是数据库用的是mysql,和大多数数据库有点不一样,它用的默认隔离级别是可重复读(REPEATABLE_READ)。

      于是问题出现了,可重复读的隔离级别中,除非更新操作执行成功,否则同一个事务对同一条记录的读取返回总是一样的,也就是说,这个版本号如果出现不匹配,那后面三次重试一定不会成功,因为重新读出来的版本号就不是最新的,根本就没变:

      

      

      具体的测试代码在:https://github.com/saaavsaaa/warn-report/blob/master/src/test/java/DBTest.java。

      也就是说这个乐观锁白写了。。。

      其实乐观锁主要是应对并发问题,减少数据库的排队的手段,其实更多是应用在抛开事务的场景下来保证执行正确的。不过说并发其实也抗不了多少并发,就算不用事务,这种使用数据库去抗所有处理的方式。。。,其实我更喜欢用Redis解决类似情况,因为单线程、因为快、因为减少持久化存储的压力,数据库其实是互联网应用中相对最经不起故障的重要部分。将计数保存在Redis中,所有操作都只对Redis的值进行操作,发现Redis中无值,通知同步服务同步数据到Redis中,然后再计算服务从Redis取值计算,不过要注意同步服务需要判断Redis有值了,就不执行写操作了。 

      另外,降低隔离级别也可以解决这个用例的问题(其实读已提交级别是其他大多数数据库的默认隔离级别),下面方法仅供参考,上生产出问题不负责。。。,下面是读未提交的测试中默认5.6版本的库需要改的配置:http://www.cnblogs.com/saaav/p/5943393.html,spring当中有七种事务传播规则:PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。(两个事务互补干扰 各自管理各自的事务),可以对乐观锁方法使用这个配置,其他事务使用默认级别,降低风险,虽然我也不知道有什么风险,目前也没时间深入研究,但是数据库开发团队既然决定使用这个默认级别,应该是有什么原因。。。

      那个测试类里还有一个测试并发的方法testConcurrentUpdate,我机器配置一般,更新并发超过1100就有失败的了,1500的时候失败已经过半了,大部分是锁超时,不过并发写到这个程度一般也不会用数据库生抗了,所以细节就不说了,知道有这么个事就成了。

    ==========================================================

    咱最近用的github:https://github.com/saaavsaaa

    微信公众号:

    转载请注明出处

  • 相关阅读:
    java类中为什么设置set和get方法操作属性
    Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
    自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表、Applications表、 Mapplings表
    自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表
    自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表、Hosts_groups表、Interface表
    21 Zabbix系统性能优化建议
    20 Zabbix 利用Scripts栏目对Hosts远程执行命令
    19 Zabbix web监控实例
    18 Zabbix 新增map中的icon图标
    自学Zabbix3.12.6-动作Action-Escalations配置
  • 原文地址:https://www.cnblogs.com/saaav/p/5943235.html
Copyright © 2020-2023  润新知