mysql并发更新数据,多用户并发修改数据解决方案。

在系统中,有一些如余额、资产、积分的数据,是要保证数据一致性的。如,一个人使用两个设备同时进行消费操作,如何保证数据一致性的问题。
我们一起来思考一下,我们的服务是分布式多节点部署,消耗方式多样(不止一处代码会对数据进行操作)。这时候,如何保证呢?


首先,我们需要确定我们使用的数据存储方式。

redis? mysql? mongo…

在redis中,数据操作为单线程,所以是可以最好避免数据不一致的问题。但如果是简单的数据覆盖,则无法利用这一优势。

包括在mysql中,我们使用写数据时,首先应该确定的一点是,我们的update不是覆盖,而是+/-(对于数值类型的,如资产)

那么,我们首先要来思考,在数值类型的数据并发修改。

  • 在mysql中

mysql有两个最火的引擎,一个叫MySAM 一个是Innodb,MySAM不支持事务,默认表锁。Innodb支持事务,默认行锁。

对于数据库有大量更新的操作,优先选用innodb作为数据库引擎,所以我们就采用innodb的行锁进行解决。

innodb的行锁注意事项:InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁。

sql写法:

update user set money_value = money_value - 20 where user_id = {userId} and money_value >= 20;

这里需要特别注意几点:条件列需要有唯一索引,就是我们例子中userId的角色,否则行锁不生效!成功会返回影响的行数,这里我们加了一个条件就是money_value >= 20,如果没有成功,我们的业务就可以进行判断。

检查索引是否失效:

explain select * from user where user_id = {userId} and money_value >= 20;

这里把update语句换成select也是可以的,重点就是验证条件是否使用索引。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐