zoukankan      html  css  js  c++  java
  • 流水号产生改用悲观锁

    业务场景:

    平台中有一个流水号功能,之前是采用乐观锁。使用乐观锁的问题是,当当前更新数据时,没有更新的时候,还是需要返回流水号。

    这就不得不重新再获取,在平台的用户访问并发很大的时候,这个乐观锁会循环很多次,导致性能下降。

    解决方法:

    使用悲观锁,由数据库来锁定,当退出该方法时,数据库自动释放锁。

    平台配置方法:

    <tx:method name="genSequenceNo" propagation="REQUIRES_NEW" isolation="READ_COMMITTED" />

    REQUIRES_NEW:

    创建一个新事务,如果当前存在事务,将这个事务挂起。也就是说如果当前存在事务,那么将当前的事务挂起,并开启一个新事务去执行REQUIRES_NEW标志的方法。
    先来总结一下结果:
    1.标志REQUIRES_NEW会新开启事务,外层事务不会影响内部事务的提交/回滚
    2.标志REQUIRES_NEW的内部事务的异常,会影响外部事务的回滚

    测试方法使用多线程模拟实际环境:

    package com.redxun.test.sys.manager;
    
    import java.util.List;
    
    import com.redxun.core.util.AppBeanUtil;
    import com.redxun.sys.core.manager.SysSeqIdManager;
    
    public class SysSeqNoThread implements Runnable {
        
        private List<String> list;
        
        public SysSeqNoThread(List<String> list){
            this.list=list;
        }
    
        @Override
        public void run() {
            SysSeqIdManager mgr=AppBeanUtil.getBean(SysSeqIdManager.class);
            for(int i=0;i<1000;i++){
                String no=mgr.genSequenceNo("ss", "1");
                this.list.add(no);
            }         
        }
    }
    package com.redxun.test.sys.manager;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    import org.junit.Test;
    
    import com.redxun.test.BaseTestCase;
    
    public class SysSeqIdTest extends BaseTestCase{
        
        @Test
        public void getSeqNo() throws InterruptedException{
            List<String> list = Collections.synchronizedList(new ArrayList<String>());
            long start=System.currentTimeMillis();
            Thread t1=new Thread(new SysSeqNoThread(list));
            Thread t2=new Thread(new SysSeqNoThread(list));
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            
            System.err.println(list.size());
            System.err.println(System.currentTimeMillis()-start);
            System.err.println("ok");
        }
    
    }

    测试了一下 产生2000个流水号,每个1.3毫秒,性能应该ok。

  • 相关阅读:
    centos7安装nginx和php7启动脚本
    centos7 安装nginx遇到的坑
    php7.2 编译遇到的坑
    yum源更新
    redis
    nginx日志分割
    Docker部署LNMP完整教程
    浅谈JavaScript词法分析步骤
    PHP面向对象中的重要知识点(一)
    Mysql精华版(命令大全)
  • 原文地址:https://www.cnblogs.com/yg_zhang/p/10785466.html
Copyright © 2011-2022 走看看