• 流水号产生改用悲观锁


    业务场景:

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

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

    解决方法:

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

    平台配置方法:

    <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。

  • 相关阅读:
    22、闭包与继承
    合并两个有序链表
    7. 整数反转
    Linux grep命令
    认识与学习BASH
    微信支付-H5网页支付开通流程
    解决 Qt5 报错 This application failed to start because it could not find or load the Qt platform plugin
    Linux 创建交换分区扩展虚拟内存
    Linux 逻辑卷管理LVM
    Linux的文件权限
  • 原文地址:https://www.cnblogs.com/yg_zhang/p/10785466.html
Copyright © 2020-2023  润新知