悲观锁和乐观锁的区别
来源:互联网 发布:中国外交有多阴险知乎 编辑:程序博客网 时间:2024/05/22 09:48
悲观锁(Pessimistic Lock)
顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock)
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
MySQL InnoDB中使用悲观锁
要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。
set autocommit=0;
//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为2update t_goods set status=2;//4.提交事务commit;/commit work;
上面的查询语句中,我们使用了 select…for update 的方式,这样就通过开启排他锁的方式实现了悲观锁。此时在t_goods表中,id为1的 那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。
上面我们提到,使用 select…for update 会把数据给锁住,不过我们需要注意一些锁的级别,MySQL InnoDB默认行级锁。行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住,这点需要注意。
使用版本号(时间戳)实现乐观锁
使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。并判断当前版本号是不是该数据的最新的版本号。
1.查询出商品信息select (status,status,version) from t_goods where id=#{id}2.根据商品信息生成订单3.修改商品status为2update t_goods set status=2,version=version+1where id=#{id} and version=#{version};
结论
两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法。
参考
- 一分钟教你知道乐观锁和悲观锁的区别
版权声明
作者:苏陌年
出处:http://zhengzy.top/
版权所有,欢迎保留原文链接进行转载:)
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 悲观锁和乐观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 悲观锁和乐观锁的区别
- 乐观锁和悲观锁的区别
- 乐观锁和悲观锁的区别
- 悲观锁和乐观锁的区别
- 病毒(3602017秋招真题)
- 如何将Oracle导出的数据导入MongoDB
- webots自学笔记(一)软件界面和简单模型仿真
- MySql数据库主(master)从(slave)配置以及原理
- hdu1250 Hat's Fibonacci
- 悲观锁和乐观锁的区别
- 欢迎使用CSDN-markdown编辑器
- 用两个栈实现一个队列
- Linux Makefile自动生成--总体流程
- OpenGl
- ArrayList list==null与ArrayList list.size()==0的区别
- 表单加分页功能
- STM32F103下模拟I2C的接口代码
- 清理缓存Caches路径下的文件