一般的防止重复插入记录方法,是设立主键,或者唯一主键来控制,但是如果主键和唯一主键都不能控制的情况下要如何处理呢?
比如我们创建用户购买票券表
tbl_ticket_rec
字段 | 描述 |
id | 自增主键 |
phone | 手机号 |
ticket_id | 票券id |
return | 是否退票--1 退票 0未退 |
time | 买票时间 |
需求描述:
一个手机号,表示一个用户,一个用户一个票id只能购买一次,但是当用户退票时,则可以再次购买,用户可以退票多次,也可以重复购买多次
需求分析:
目前该表主键只有id做为自增主键,如果在高并发的情况下控制插入,那么就需要要每次插入时先查看一下库中是否存在该用户购票记录
select 1 from tbl_ticket_rec where phone = xx and return =0
如果库中不在存在购买且未退的记录,则可以插入库中。
但是在高并发的情况下,当我们从select 到 insert 过程中,可能存在其它线程入库的结果,导致select 结果不准确
方案改进:
这时候就需要调整一下select机制
inset into tbl_ticket_rec(phone,ticket,return) select '13700000000','0001','00' from dual where not exists (select 1 from tbl_ticket_rec where phone ='13700000000' and return ='0')
其中dual 是一张虚拟表
那么其对应的mapper文件,如以如下编写
insert into tbl_ticket_rec
phone,
ticket_id,
return,
select
#{phone,jdbcType=CHAR},
#{ticketId,jdbcType=CHAR},
#{return,jdbcType=CHAR},
from dual where not exists (select 1 from tbl_ticket_rec where #{phone,jdbcType=CHAR} and return = #{return,jdbcType=CHAR})
结论:
通过以上改进,可能有效的控制高并发情况下的数据入库重复问题
来源地址:https://blog.csdn.net/shenshiheng2006/article/details/128726715