Mysql的锁
0.目录
问题并发来源
悲观锁定义
悲观锁方法
行锁表锁
行锁表锁各种情况
乐观锁
1.问题来源
就是一数据表的数据 在两个人同时修改的时候 会出现混乱 例子:如一个字段记录status=1 表示可以下单 货品只有1个的时候 a下单的同时b也下单 ; a有修改status的机会 b也有修改的机会;但是a下单成功 b下单未知 这就会出现矛盾 与现实的不想符合!
2.悲观锁
悲观锁是对数据被的修改持悲观态度(认为数据在被修改的时候一定会存在并发问题),因此在整个数据处理过程中将数据锁定。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在应用层中实现了加锁机制,也无法保证外部系统不会修改数据)。
(人话翻译:就是悲观锁认为所有的数据表操作都会有并发问题 所以依靠自身的锁机制来一个锁定一次处理完好之后 再进行下一次的数据操作)
3.悲观锁的方法
在上面的场景中,商品信息从查询出来到修改,中间有一个处理订单的过程,使用悲观锁的原理就是,当我们在查询出goods信息后就把当前的数据锁定,直到我们修改完毕后再解锁。那么在这个过程中,因为goods被锁定了,就不会出现有第三者来对其进行修改了。要使用悲观锁,我们必须关闭mysql数据库的自动提交属性。
set autocommit=0;
//设置完autocommit后,我们就可以执行我们的正常业务了。具体如下:
//0.开始事务
begin;/begin work;/start transaction; (三者选一就可以)
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;/commit work;
使用了select…for update的方式,这样就通过数据库实现了悲观锁
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁。如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE
4.Row Lock与Table Lock
默认Row Lock 只要指定id 就是行锁 没有指定就是表锁
5.锁定分析
5.1 明确指定主键,并且有此数据,row lock
5.2 明确指定主键,若查无此数据,无lock
5.3 无主键,table lock
5.4 主键不明确,table lock
5.5 明确指定索引,并且有此数据,row lock
5.6 明确指定索引,若查无此数据,无lock
6.乐观锁
悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 。
乐观所:读取数据时不锁,更新时检查是否数据已经被更新过(添加where条件即可判断是否更新了!),如果是则取消当前更新,一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁 适用于高并发的情况