《mysql基础》6-锁2
上面的一节总结了一下全局锁/表锁,这次讲行锁
Mysql支持行锁是有引擎InnoDB实现的,MylSAM不支持行锁,所以在操作业务时会锁住整个表,那这样出现并发的情况就大大扩大了。java编程的时候,我们有锁范围最小原则,不必要的数据不要加锁,但是表锁会锁定整个表内容,所以不适合高并发的情况。
数据行锁的意识就是在需要的数据行上加锁,
比如下面这条语句
update t1 set age = 18 where name = 'lisan'
InnoDB会在lisan这条记录上加锁,不会锁住整个t1表
这样的话,并发的范围就大大缩减了,执行update t1 set age=22 where name = 'wanger'的操作就不会被阻塞。
需要注意的点:
跟redoLog/binLog的两阶段提交一样,锁也分为两阶段
1:在需要的时候获取锁
2:在commit之后统一释放锁。
例子 :sessionA执行了两个操作
begin:
update t1 set age = 18 where name = 'zhangsan';
update t2 set address = 'heihei' where name = 'zhangsan';
commit;
sessionB如果在想执行查询操作
select * from t1 where name = 'zhangsan';
必须等到sessionA的commit操作,所以现实业务中经常会出现这种情况。
图书商城 BookA促销,有很多人要购买,小明和小黑都是抢购用户。
基本操作
begin:
-- 小黑账户扣钱;
update account set account = account-10 where name = '小黑';
-- 商城书数量-1;
update book set num = num-1 where name = 'bookA';
commit;
类似小明也要执行该操作,这个时候我们要注意,因为 book表会被大量用户访问,所以该表的锁时间要尽量的短,根据两阶段锁的定义,在需要的时候获取锁,那么我们就要在编程的时候特别注意:
有大并发场景的数据要放在最后获取锁。
尽管有上面的注意事项,我们还是会出现死锁的情况,对于这样的情况,可以开启死锁检测,但是一定要注意控制并发度,在业务场景中,不能有过多的并发请求同时访问一条数据,保证死锁检测的线程足够小。
上一篇: 在C++类的外部调用类的私有方法
下一篇: mysql语句执行中的锁情况