具体描述如下,当有一条数据时,首先查询这条记录是否存在,存在则更新,不存在则创建,但是由于并发很高,导致数据重复创建。
加了唯一健索引,虽然数据不会重复,但是会报错,有没有好办法完美解决这个问题?
尝试了加锁,但是只有对数据更改有效,重复插入还是会出现,
使用redis记录状态,虽然缓存速度很快,但不是原子操作,更高并发下,还是会有问题。还有一个问题是,使用了事务,一旦回滚,还要删除缓存,维护起来麻烦
具体描述如下,当有一条数据时,首先查询这条记录是否存在,存在则更新,不存在则创建,但是由于并发很高,导致数据重复创建。
加了唯一健索引,虽然数据不会重复,但是会报错,有没有好办法完美解决这个问题?
尝试了加锁,但是只有对数据更改有效,重复插入还是会出现,
使用redis记录状态,虽然缓存速度很快,但不是原子操作,更高并发下,还是会有问题。还有一个问题是,使用了事务,一旦回滚,还要删除缓存,维护起来麻烦
一、如果仅从解决问题来说replace into不错,其实也可以 insert ignore,这样可以忽略错误,因为你加了唯一索引,也能保证唯一插入
二、事务并不能解决高并发的问题,他解决的是原子性问题,保证了整个流程的完整性
三、如果是高并发情况下,redis是不错的解决方案了,在redis中加一个排它锁,当一个请求进来了先加排它锁,等sql执行完释放排它锁,redis的排它锁实现方式很多,比如用字符串set('lock',1),当lock为1的时候其就进入 while 循环,直到lock为0,
四、还有一个方案就是加乐观锁或者悲观锁,比如悲观锁:select id from XXX for update,但是这个和实际的业务逻辑有很大的关系,不知道你的业务逻辑适不适合表加锁的 方案
两个方案
1.INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; //插入一条数据,存在则更新,需要用到唯一索引
2.用redis的setNX命令
1:数据库唯一索引。
2:redis实现分布式锁(set NX EX 很多人都说不可靠,其实还是挺可靠的,公司很多项目用了,也没有出过什么问题),关于redis实现分布式锁安全的论证:https://mp.weixin.qq.com/s/JT...
3:基于ZooKeeper实现分布式锁。
4 回答13.2k 阅读✓ 已解决
5 回答7.7k 阅读✓ 已解决
4 回答2.3k 阅读
1 回答1.5k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
1 回答1.5k 阅读✓ 已解决
1 回答950 阅读✓ 已解决
还是加唯一索引,try catch捕获错误,判断错误错误码是否为唯一索引的错误码,如果是则跳过