首先悲观锁和乐观锁是基于业务逻辑来讲的,他们和数据库的锁是不同的概念,数据库的锁是实现数据库事务的机制。
乐观锁就在并发情况下,避免覆盖更新的一种机制,是程序员自己通过添加一个version字段实现,每次load数据都读出这个字段,在更新的时候比较下这个version字段是否一致而避免覆盖了不同的版本。至于他为什么叫乐观锁就是因为认为他的并发情况不高,即使发生并发导致更新失败也可以忍受。(适度控制并发,占用资源少,性能高,当然完全放任不管性能更高,根本不占用资源)
而悲观锁是基于数据库的锁机制来实现的(可以理解为我用了事务就是使用了基于数据库的锁机制来实现悲观锁),直接通过锁住并发的资源,来减少并发产生的问题,数据库做到这一点的就是事务啦。
数据库事务和锁机制是密不可分的,数据库事务就是通过锁机制来实现的,并且数据库事务隔离级别就是因为不同的级别,而采用不同的数据库锁,也这是数据库锁机制和事务隔离级别之间的关系。
如下是测试代码。
case 1 ================================
窗口1
begin tran select * From tb_test where id=1
窗口2
update tb_test set content='yyy ' where ID=1
result: (1 row(s) affected)
这里采用了默认隔离级别,所以查询是没有加锁,也可以正常更新。
case 2 ================================
窗口1
begin tran select * From tb_test with (updlock) where id=1
窗口2
update tb_test set content='yyy ' where ID=1
result: 无
这里发生了堵塞,因为这里显示使用了U锁。
case 3 ================================
窗口1
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ begin tran select * From tb_test where id=1
窗口2
update tb_test set content='yyy ' where ID=1
result:无
这里也发生了堵塞,我并没有显示使用U锁,但是是使用了更高级别的隔离级别,这里的隔离级别默认把SELECT查询添加了U锁,所以也导致了另外一个连接无法更新。
这里也看出了不同的隔离级别和不同的锁之间的关系,不同隔离级别是基于不同的锁来实现的。