如果不改变表结构,insert 貌似只能加锁 先查询有没有记录,有则使用 version=version+1 更新;否则加锁分布式锁 redis 等,再查询记录,为空则 insert ,最后释放锁。使用行锁间隙锁记录锁等都不能解决多次 insert 的问题。
我们过去遇到类似的问题是这样处理的,仅供参考: 定义队列,所有插入放入队列,并不直接操作数据库 一个工作线程从队列取出来请求,插入数据库成功后把回调的 task 放到回调队列 回调队列工作线程执行回调 这样就不存在并发操作数据库的问题了
并发要求多少?这种共享变量的 读取-新增 操作不上锁都会有并发问题吧?可以试试把锁的粒度控制在最小,试试 select version from table where userid = ${} and business_type = ${} order by version limit 1 for update; where 条件字段要索引。
加个 current_version(user_id, business_type, current_version) 表,锁这个表来实现 inc current_version, 和 insert 放一个事务里,也不用去 max(version) 了-- 就是不知道业务有不有其他要求 -- 当然本质上跟 分布式锁,或者 redis 锁是一样的,开场景吧,我觉得大部分用不着分布式锁
[quote]同一个用户账号在多端同时操作这个业务的配置信息[quote] 你这业务的粒度在 userid ,这怎么会有高并发呢,不要把并发和高并发一概而论哦。 你这个场景直接用乐观锁就行了,并发场景下只能成功一个,各大数据库应该都有 row version 的字段类型。
@heiya 你需要多高的插入性能,每秒 1W 够不够 ?如果可以接受,那就 OK 。回调是为了在别的线程处理剩下的事情,否则你需要的队列工作线程处理剩下的事情,会占据这个线程处理数据库写入的性能,放到队列,由回调处理线程处理就不存在这个问题了。