mysql - 先查找,如果不存在就插入数据 并发出现问题

查看:440
本文介绍了mysql - 先查找,如果不存在就插入数据 并发出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

验证用户信息时,先查找用户信息,如果没有则创建一条消息,在并发的时候,会发现,出现两条相同的用户信息。
目前我的解决方案是:建索引,将第二次插入报错屏蔽。
我想问的是,有没有技术能更好的解决这类并发问题

解决方案

如果没有则创建一条消息

// Case 1. 该条消息有且仅有一条创建的业务逻辑
该种情况下只需将该段代码同步或加锁,即可避免在高并发下发生脏读的问题。

// Case 2. 该条消息有多处创建的业务逻辑
建议将 查询-创建 操作原子化,通过为user加一个Unique字段即可实现。

======== 2016-02-22 更新 ========

不同用户创建数据不应该相互影响,那么该如何应用同步或者锁

建议新建一个账户锁类,然后使用它来锁定。代码如下:

import java.util.concurrent.ConcurrentHashMap;
/**
 * AccountLock 为单独的账号加锁
 */
public class AccountLock {
    private final ConcurrentHashMap accounts = new ConcurrentHashMap();
    public synchronized void lock(String account) throws InterruptedException{
        while ( accounts.contains(account) ){
            wait();
        }
        accounts.put(account, true);
    }

    public synchronized void release(String account) {
        accounts.remove(account);
        notify();
    }
}

具体业务逻辑下:

    private static final AccountLock lock = new AccountLock();
    public void createAccount(/* 传参 */) {
        String account = /* 账号 */;
        
        lock.lock(account);
        try {
            //业务逻辑
        } finally {
            lock.release(account);
        }
    }

这篇关于mysql - 先查找,如果不存在就插入数据 并发出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆