关于数据库高并发插入的版本号问题

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

返回顶部