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。

  • 相关阅读:
    NFC技术:让Android自动打开网页
    NFC技术:让Android自动运行程序
    NFC技术:概述
    路由器端口映射实现外网访问本地服务器
    Java之MySql数据库链接
    最短路径之Dijkstra算法及实例分析
    各种排序算法的时间性能比较
    C#实现基于ffmpeg加虹软的人脸识别
    虹软SDK在nodejs中的集成
    Android 虹软2.0人脸识别,注册失败问题 分析synchronized的作用
  • 原文地址:https://www.cnblogs.com/yg_zhang/p/10785466.html
Copyright © 2011-2022 走看看