秒懂乐观锁与悲观锁

在数据库的改查操作当中,多用户的并发操作极有可能产生冲突。产生冲突的结果大概有两种:更新覆盖[0]和脏读[1]。

应对方法便是对并发操作的控制

最常用的策略是加锁,锁有两种,一种叫悲观锁,另一种叫乐观锁

悲观锁:

  • 顾名思义,就是从悲观的角度去看待解决问题,假设会发生冲突,所以你要独占(锁住)整个资源,宁可阻塞后来的操作,也要保证数据完整性。悲观锁虽然悲观的处理问题,但是其策略强有力的保证了数据的完整性。悲观锁的粒度最小达到了行级(只锁定该行),有效的减小了冲突,提高系统的吞吐量。

乐观锁:

  • 顾名思义,就是从乐观的角度去看待解决问题,假设不会发生冲突,大家都可以来查,只是在改动的时候需要检查是否是最新的数据,倘若数据不是最新的,则驳回改动。也就是说,倘若执行乐观锁策略,需要多增加一个字段(一般是Version)用来判断数据是否是最新的。然后更新后Version++。那么对查询没有限制,所以发生冲突时的影响一般是造成脏读。

应用:

悲观锁与乐观锁没有好坏优劣之分,它们擅长应对不同的情况。

  • 悲观锁适合多改动的场景,最好是并发/数据量小或者不允许脏读的场景。(例如balance)
  • 乐观锁适合多查询的场景,并且对脏读要求不高的场景。(只查不改的,例如log,report。)

实现:

乐观锁在不同数据库有不同的实现方式,一般需要自己动手实现写SQL语句,在流行的框架比如Hibernate中,已经封装好了实现,在使用乐观锁策略的字段前加@Version, Hibernate在更新记录时会自动校验该字段。

脚注:
[0]更新覆盖: 一个事务的更新操作结果并发的被其它事务的更新操作结果覆盖。
[1]脏读:当一个事务读取的数据由于其它并发事务的操作造成的数据不真实时,就发生了脏读。

参考资料:
http://blog.csdn.net/hongchangfirst/article/details/26004335
www.cnblogs.com/Bob-FD/p/3352216.html

原文链接:
http://blog.csdn.net/timo1160139211/article/details/74984848

你可能感兴趣的:(数据库-DB)