锁机制

锁是控制“共享资源”并 发存取的一种机制
1、更新丢失update lost
“更新丢失”是一个典型的数据库问题,在所有的多用户环境都可能遇到。简单的描述下“更新丢失”的产生:
1)session1的一个事务查询一行数据展现给user1。
2)另一个session2的一个事务也查询同一行数据展现给user2。
3)然后user1通过应用程序更新并提交这行数据,他完成了整个事务。
4)User2也同样通过应用程序更新并提交这行数据,他也完成了整个事务。
上面的过程就会造成“更 新丢失”,因为所有在第三步修改的数据全部都会丢失。一个典型的例子就是售票系统,比如一个用户(user1)在网上预定查询到1号位的票还没售出,同时 另一用户(user2)在现场售票点查询也查到1号位票没售出。然后user1预订了这张票(即售票系统更新了数据库表中1号位的信息“已预订”),而这 时user2又将这张票卖给了现场购票的人(即user2也成功更新1号位的信息“已售”,覆盖更新了user1的更新),等到user1去拿票的时候他 预定的票却已经被卖出去了,这就是应用系统出现的一个严重的问题。
2、悲观锁
“悲观锁”实际上是一种使用锁的方式,即user1主观的认为会发生“更新丢失”,所以在他查询的时候就对查询结果的数据“立刻”加锁来防止发生“更新丢失”。这是一种“悲观”的想法,所以叫做“悲观锁”。
select * from tb1 for update--悲观锁

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
死锁例子:
oracle中打开两个会话,会话1中更新A表,会话2更新B表,此时,如果想在会话2中更新A表,会出现阻塞。但如果同时又想在会话1中更新B表,就会导致死锁。

你可能感兴趣的:(锁机制)