Mysql 先SELECT 后UPDATE 问题

最近做一个统计;需要把一个字段(存放数据是json)里某一个数字加1 然后在修改该字段;当时就那么一写最后发现该数据和明细对不上; 其实这个应该是并发引起的,先select 在update 这样写其实会出现一些问题

参考篇文章

###第一种解决方案

事务,即用一个事务来包裹上面的SELECT+UPDATE操作+写共享锁。

读共享锁是通过下面这样的SQL获得的:SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;

如果事务A获得了先获得了读共享锁,那么事务B之后仍然可以读取加了读共享锁的行数据,但必须等事务A commit或者roll back之后才可以更新或者删除加了读共享锁的行数据。

如果事务A先获得了某行的写共享锁,那么事务B就必须等待事务A commit或者roll back之后才可以访问行数据。

SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;

###第二种解决方案

乐观锁,上面是一种观锁机制,而且SELECT...FOR UPDATE方式也不太常用

SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1 WHERE counter_field='上面select出来的值' ;

这样可以根据UPDATE返回值来判断是否更新成功,如果返回值是0则表明存在并发更新,那么只需要重试一下就好了。

  1. 如果对读的响应度要求非常高,比如证券交易系统,那么适合用乐观锁,因为悲观锁会阻塞读

  2. 如果读远多于写,那么也适合用乐观锁,因为用悲观锁会导致大量读被少量的写阻塞

  3. 如果写操作频繁并且冲突比例很高,那么适合用悲观写独占锁

mysql锁相关学习

转载于:https://my.oschina.net/u/729139/blog/702514

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值