解决数据库报唯一性约束错误的实践

本文介绍了在遇到数据库报唯一性约束错误时的三种解决方案:1)通过锁机制原子化查询和插入;2)使用双重检查锁优化性能;3)利用Redis的setnx特性在插入数据库前避免冲突。这些策略既保证了数据的唯一性,又优化了系统性能。
摘要由CSDN通过智能技术生成

猿们好,我是honery,今天来给大家唠一唠如何避免数据库报唯一性约束的错误。

一、问题的引出

  首先抛出一个问题,如何保证数据库表中的某列的值都不一样呢?相信大家很容易想到给该列加上唯一性约束,这样就能保证业务逻辑的正确性了。实际的使用中,尤其高并发场景下,很容易出现插入同一条记录的情况,该情况下数据库会报违反唯一性约束的错误。总不能让数据库一直抛这个错误吧。于是我们想到可以在业务代码中加上该列值是否为空的判断,判断为空时再行插入,于是问题就解决了。

  问题真的解决了吗?说是,你就too young too simple了。有没考虑过高并发场景呢?如果多个线程同时在某次插入前去判空,显然判断的结果都是空,那么第一次插入成功后,后续的插入动作都会报违反数据库唯一性约束的错误。总不能让日志一直报错吧,该如何解决呢?

二、问题的解决方案

  这个问题其实是个典型的问题,可以有很多种解决方案,小编这里就简单提供三种解决策略。方案很简单,猿们跟上思路~~

2.1 通过锁机制,将查询和插入原子化

  相信很多小伙伴很容易就能想到这个方案,通过锁机制(如内置锁,synchronized)将记录是否存在的查询动作和插入新记录的动作放在一个同步锁中,实现的关键代码如下:

@Transactional
public synchronized void insertWhenIdIsEmpty(Qingmj qingmj) {
    log.info("进入时间:"+System.currentTimeMillis());
    log.info(qingmj.toString());
            
    Qingmj qingmj_old = qingmjMapper.getQingmjById(qingmj.getId());
    
    try {
        //等待10s,制造并发场景
        Thread.sleep(15000);
    } catch (InterruptedException e) {
        log.warn("睡眠等待过程异常",e);
    }
            
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值