高并发下数据库插入重复数据

skyline520 发布于 2013/05/28 12:23
阅读 10K+
收藏 3
ServiceA{
     // 根据username查询数据库中是否存在该数据
     Method isInDB(String username); 
     //保存用户
     Method saveUser() {
           boolean  flag = Method isInDB(username);
           if(!flag){
              //判断数据库中没有才 执行insert 操作
           }
     }
}
以上是我的java代码,我用loadrunner 进行压力测试,在saveuser前设置集合点,直接使用300用户并发操作,结果数据库会保存进许多重复username的记录,我自己从网上也查了许多资料有人给了我以下建议
1、保存用户逻辑采用储存过程操作,把并发压力交给数据库处理
2、数据库对username字段加上唯一约束,这样插入重复记录时 抛出异常,利用事务进行回滚
除了以上两种方法外,我想请大家给出第三种解决方案,其实这种就类似与高并发下的用户注册功能


加载中
1
lkclkc888
lkclkc888
   //缓存map,防止同一时间多个相同用户进行数据保存
  private static  Map<String,String> map = new ConcurrentHashMap<String,String>();
    
   private boolean isInCache(String username){
        synchronized (map)
        {
            if(map.containsKey(username)){
                return true;
            }else{
                map.put(username, username);
            }
        }
       return false;
    }
   //验证数据库中是否存在同名用户
   public abstract boolean isInDB(String userName);
   
   public void saveUser(String username){
       if(!isInCache(username)){
           if(!isInDB(username)){
               saveUser();
               //移除map中的key
               synchronized (map)
            {
                map.remove(username);
            }
           }
       }
   }
   //保存进数据库

   public abstract void saveUser();

通过一个同步map实现相同用户名在统一时间只存在一次保存数据。

在保存数据之前,验证数据库中是否还存在同名数据,如果不存在,直接保存.


skhuhu
skhuhu
用set 不好吗··直接去重
skyline520
skyline520
虽然没有去试验,感觉你这个方案有点靠谱 呵呵
skyline520
skyline520
可是看了你的这个之后,我发现如果是分布式部署,是不是还会有问题
skyline520
skyline520
哥们 你很给力啊,直接给上代码了 呵呵
0
skyline520
skyline520
先做前排 ,先顶起来 呵呵,针对以上两种方案,我还没有实际去验证可行性,期待大家的回答
0
铂金胖子
铂金胖子
用数据库唯一索引,或者主键 做约束,比较靠谱。
0
JKnife
JKnife

这样试试看:

INSERT INTO the_table (cl1, cl2, ... , cln) SELECT cl1, cl2, ..., cln FROM (SELECT ? AS cl1, ? AS cl2, ... , ? AS cln) X WHERE NOT EXISTS ( SELECT id FROM the_table WHERE username=?)

0
王瑞平
王瑞平

查什么都不好使

唯一是肯定要做的

0
skyline520
skyline520
顶起来,还有人来回答么
0
skyline520
skyline520
@红薯 不知道你能看到不,期待红薯来回答下,osc 如何解决高并发插入的
0
huan
huan

1  saveUser 方法加上 synchronize 关键字

2 saveUser 加上序列化事物控制

0
skyline520
skyline520

引用来自“huan”的答案

1  saveUser 方法加上 synchronize 关键字

2 saveUser 加上序列化事物控制

这个性能估计比较低了
0
duty
duty
你的问题是用户名重复.其实用户名这东西你必须要做唯一约束的.插入之前必须做唯一性检查.
返回顶部
顶部