美文网首页
高并发与锁

高并发与锁

作者: 简书说我的昵称违规 | 来源:发表于2017-06-09 22:59 被阅读65次

DRP学习中,我们对可能引起并发操作的情况使用了锁,这次先理论上看看并发控制与锁的一些内容吧。

并发控制

在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是并发性。典型的冲突有:
** 1、丢失更新(Lost updates)**
一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改为2,用户B把值从2改为6,则用户A丢失了他的更新。
** 2、脏读(Dirty reads)**
当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改为2,用户A读到的值仍为6。
3、不可重复读(Non-repeatable reads) 当一个进程读取了一笔数据后,另一个进程更新了同一笔数据,然后第一个进程再次读取同一笔数据,却得到了 与第一次读取不同的结果。
在事务A更新记录之后(update Customers set Name = 'B' where Name = 'A'),事务B读取相同记录(select Name form Customers where Name = 'A'),但事务B拿到的是事务A更新之后的数据(Customers.Name的值为'B'),在事务B读取记录之后,事务A进行了事务回滚(Customers.Name的值为'A'),导致事务B的数据是不真实的。 4、幻读(Phantoms) 幻读与脏读的相似之处在于:两者都是两次读取的结果不一致。不同之处在于:幻读是两次读取的记录数量不一致,而脏读是两次读取的记录的数据不一致。事务A读取记录之后(select * from Customers where Name like 'A%'),事务B又插入了符合事务A读取条件的新记录(insert into Customers(Name) values('AAA')),那么当事务A再用相同条件读取记录时,得到的集合却与上一次读取不同(多了记录)。

解决方案:线程同步和加锁

通常我们解决并发问题使用同步和加锁两种方式。同步中,我们通过Java中的synchronized关键字来实现,但这样通常会带来性能和效率上的一些问题。这次,我们主要讲解锁。锁机制中,我们可以根据不同情况使用悲观锁或乐观锁。

  • 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 对于悲观锁,我们可以提供一个值作为锁的参数。比如一个键默认会被锁定15秒。15秒过后,如果你还没有手动的释放锁,那么使程序自动的为你释放。 悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。
  • 乐观锁: 乐观锁(Optimistic Lock), 就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。 而乐观锁机制在一定程度上解决了数据库性能开销这个问题。它大多是基于数据版本( Version )记录机制实现。 可以使用版本号、时间戳等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

比较

  1. 两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
  2. 悲观锁和乐观锁最大的区别是是否一直锁定资源,悲观锁在事物的全流程锁定数据,乐观锁不锁定数据(用读写锁是阻塞事物,而用乐观锁则会导致回滚,这个是一种事物冲突后的不同锁的表象)。
  3. 悲观锁和乐观锁都是为了解决丢失更新问题或者是脏读。悲观锁和乐观锁的重点就是是否在读取记录的时候直接上锁。悲观锁的缺点很明显,需要一个持续的数据库连接,这在web应用中已经不适合了。

注:转http://www.cnblogs.com/soundcode/p/6571447.html

相关文章

  • 高并发与锁

    DRP学习中,我们对可能引起并发操作的情况使用了锁,这次先理论上看看并发控制与锁的一些内容吧。 并发控制 在多用户...

  • java并发

    1.并发编程中的锁 并发编程中的各种锁java高并发锁的3种实现Java并发机制及锁的实现原理 2.线程池核心线程...

  • 信号量semaphore

    java高并发程序设计 内部锁Synchronized与重入锁ReentrantLock,一次都只允许一个线程访问...

  • Mysql锁有哪些,如何理解 --- 2021-09-14

    按锁的粒度分: 行锁,锁某行数据,锁粒度最小,并发度高 表锁,锁整张表,锁粒度最大,并发低 间隙锁,锁的是一个区间...

  • Java-线程总结

    一、高并发线程1.显示锁(Reetrentlock)/隐式锁(sychronized)2.独占锁(写锁)/共享锁(...

  • etcd:一款比Redis更骚的分布式锁的实现方式!用它

    分布式锁 关于为什么要有分布式****锁这个东西,欢迎阅读我的zk分布式锁的实现,介绍了单机高并发、分布式高并发的...

  • 2019-03-18文章精选

    1.深入理解 MySQL ——锁、事务与并发控制 各种锁、事务与并发,写得很详细。 2.剖析分布式锁 redis部...

  • 乐观锁和悲观锁

    1.乐观锁和悲观锁的概念 乐观锁:假设不会发生并发冲突,数据库的并发操作只在提交的时候检查数据的完整性,并发效率高...

  • java并发-独占锁与共享锁,公平锁与非公平锁,重入锁与非重入锁

    java并发-乐观锁与悲观锁,独占锁与共享锁,公平锁与非公平锁,重入锁与非重入锁 java 中的锁 -- 偏向锁、...

  • Spring Elasticsearch data 乐观锁并发控

    Spring ElasticSearch data 乐观锁并发控制 乐观锁与悲观锁 悲观锁(Pessimistic...

网友评论

      本文标题:高并发与锁

      本文链接:https://www.haomeiwen.com/subject/lfxqqxtx.html