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

查看 500|回复 49
作者:avadakur   
我的数据库设计的是如下格式
userid | business_type | config_id | total_version
(userid,business_type) 这两个的组合会控制 total_version 版本号字段,每次在对(userid,business_type)更新或者插入时,都会让 total_version 自增然后插入或者更新。
问题:
在高并发插入的情况下,我先获取(userid,business_type)的最大版本号,然后执行插入的这个过程,会导致多个插入记录同时都获取的 totoal_version= 1 然后两个都会执行 version + 1 = 2,导致用户版本号丢失一次更新记录。这个问题要怎么解决呢?
最终解决方案:使用 Redis 中存储 userid,business_type 的版本号,通过 Redis 单线程来获取最新版本号,冗余一张用户业务版本号表。
yjhatfdu2   
最终解决方案:使用 Redis 中存储 userid,business_type 的版本号,通过 Redis 单线程来获取最新版本号,冗余一张用户业务版本号表。
coderxy   
开事务
themostlazyman   
用一个自增操作不就完事了?
yjhatfdu2   
更新的时候:获取版本号,然后条件加版本号
themostlazyman   
如果不是必须先获取当前 version 做业务操作然后再更新,那么直接 update version set version=version+1 where xxxx 就可以了,如果必须先获取 version 再做一些业务操作再更新,就得开事务了,然后高并发的情况还得考虑事务失败概率高的问题,可以根据你的数据库实际情况考虑使用显式锁来减少事务冲突导致的失败
avadakur
OP
  
@themostlazyman 上锁的话,并发少行锁,高的话可以用 reids 上锁。
shinelamla   
@coderxy 数据库里的每个用户和业务类型 都有一份自己的总版本号 并不是这个表的 total_version 是一个自增的
avadakur
OP
  
想了一下开不开事务都没什么用,除非你开的隔离级别是已提交读。
应该用乐观锁,既然你是”先获取(userid,business_type)的最大版本号“,那你在更新或者插入之前就知道了最大版本号了,在更新操作的时候,update set total_version = total_version + 1 where userid =xxx and business_type=xxx and total_version = 你刚才获取的版本号
shinelamla   
@themostlazyman 更新的时候是没问题的 可以用 CAS 来控制,但是我现在在 Insert 的时候不知道要怎么控制
您需要登录后才可以回帖 登录 | 立即注册

返回顶部