为什么乐观锁效率高于悲观锁?(转,该文章没有给出满意回答)

add by zhj: 这个问题最后没有给出另人满意的答案,我在 MySQL事务隔离级别,锁 中给出了我的理解


原文:为什么乐观锁效率高于悲观锁?

标 题: 【合集】为什么乐观锁效率高于悲观锁? 发信站: 饮水思源 (2008年05月19日12:29:00 星期一), 站内信件 ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月14日21:13:24 星期三) 提到: 书上都说如果是长事务高并发那么悲观锁的效率很低,可是我有一点疑问实在想不通 如果若干个事务并发访问同一条记录: 悲观锁是第一个访问的事务成功,其他事务等待 乐观锁是第一个提交的事务成功,其他事务回滚 不都是一个成功,其他失败吗?效率有何差异?有点想不清楚了 ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月14日21:25:10 星期三) 提到: 乐观锁是乐观地认为事务的并发造成的冲突很低,与其用悲观锁锁住整张表,还不如用乐 观锁。到底乐观锁效率高还是悲观锁效率高,要看具体的应用的。 【 在 magiczhang 的大作中提到: 】 : 书上都说如果是长事务高并发那么悲观锁的效率很低,可是我有一点疑问实在想不通 : 如果若干个事务并发访问同一条记录: : 悲观锁是第一个访问的事务成功,其他事务等待 : 乐观锁是第一个提交的事务成功,其他事务回滚 : 不都是一个成功,其他失败吗?效率有何差异?有点想不清楚了 ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月14日21:30:28 星期三) 提到: 悲观锁不会锁住整张表,只会锁住要更新的记录吧 而且别的事务只要不也申请加锁,还是可以读被加锁的记录的,如果别的事务也要修改记 录,那么即使用乐观锁还是只有先提交的事务成功,其他事务回滚,那乐观锁有什么优势 呢? 【 在 caobo 的大作中提到: 】 : 乐观锁是乐观地认为事务的并发造成的冲突很低,与其用悲观锁锁住整张表,还不如.. : 观锁。到底乐观锁效率高还是悲观锁效率高,要看具体的应用的。 ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月14日21:39:18 星期三) 提到: 锁表还是锁记录不是由你决定的,数据库会在锁表,锁记录,或者锁部分记录(比如一张 表分成多个文件,它就锁一个文件)中选一。被加锁的记录不一定能读,要看事务的隔离 级别。而且锁本身也占资源。一切都跟具体应用有关,都要看具体应用需要哪种锁。 【 在 magiczhang 的大作中提到: 】 : 悲观锁不会锁住整张表,只会锁住要更新的记录吧 : 而且别的事务只要不也申请加锁,还是可以读被加锁的记录的,如果别的事务也要修.. : 录,那么即使用乐观锁还是只有先提交的事务成功,其他事务回滚,那乐观锁有什么.. : 呢? ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月14日21:47:11 星期三) 提到: 举个上课时老师讲的例子,一个订票过程,先选择一张票,然后预定。显然,这个事务的 隔离级别应该是Serializable的,因为要防止票被重复预定。但是一旦设为Serializable 的隔离级别,意味着一个时间里只有一个人可以预定。事实上有很多人要同时预定票,但 并发程度并不高,因为订同一张票的概率很低很低。这时候用乐观锁显然比悲观锁好。 【 在 magiczhang 的大作中提到: 】 : 悲观锁不会锁住整张表,只会锁住要更新的记录吧 : 而且别的事务只要不也申请加锁,还是可以读被加锁的记录的,如果别的事务也要修.. : 录,那么即使用乐观锁还是只有先提交的事务成功,其他事务回滚,那乐观锁有什么.. : 呢? ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月14日22:47:01 星期三) 提到: 你的概念错了吧。 隔离级别设成Serializable和悲观锁是两码事,悲观锁相当于select ... for update 事实上一般都是设成read commited,然后选择悲观锁或者乐观锁来解决unrepeatable re ad问题 事务1 select ... for update的时候 ,事务2光select不加for update是可以的 【 在 caobo 的大作中提到: 】 : 举个上课时老师讲的例子,一个订票过程,先选择一张票,然后预定。显然,这个事.. : 隔离级别应该是Serializable的,因为要防止票被重复预定。但是一旦设为Serializ.. : 的隔离级别,意味着一个时间里只有一个人可以预定。事实上有很多人要同时预定票.. : 并发程度并不高,因为订同一张票的概率很低很低。这时候用乐观锁显然比悲观锁好。 ☆──────────────────────────────────────☆ volezheng (Mark Williams) 2008年05月14日23:19:56 星期三) 提到: 对数据库没什么研究,我猜下意思吧 悲观锁的话,第一个事物来,就锁住了,其他事务要等待,这样其他事务都不能进行下去 ,所以说并发程度很低 乐观锁的话,大家都能进行下去,并发程度很高,虽然最后只能有一个成功,但是至少没 有让大家等待 说的效率应该是指并发程度吧?是不是这个意思? 【 在 magiczhang 的大作中提到: 】 : 书上都说如果是长事务高并发那么悲观锁的效率很低,可是我有一点疑问实在想不通 : 如果若干个事务并发访问同一条记录: : 悲观锁是第一个访问的事务成功,其他事务等待 : 乐观锁是第一个提交的事务成功,其他事务回滚 : 不都是一个成功,其他失败吗?效率有何差异?有点想不清楚了 ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月15日00:25:07 星期四) 提到: 不等待但最后又要回滚,那不是更糟 就像你订一张票,你开始以为那张票存在,为了买这张票你花了五分钟填表格,结果最后 发现票没了,那不是更郁闷? 反正最后只有第一个提交的事务能提交,那并发还有什么意义呢? 【 在 volezheng 的大作中提到: 】 : 对数据库没什么研究,我猜下意思吧 : 悲观锁的话,第一个事物来,就锁住了,其他事务要等待,这样其他事务都不能进行.. : ,所以说并发程度很低 : 乐观锁的话,大家都能进行下去,并发程度很高,虽然最后只能有一个成功,但是至.. : 有让大家等待 : 说的效率应该是指并发程度吧?是不是这个意思? ☆──────────────────────────────────────☆ volezheng (Mark Williams) 2008年05月15日00:53:54 星期四) 提到: 可能有这种情况,一个事物有很多步骤,一般不会所有事务都成功 那么就能最大程度保证并发,虽然可能会牺牲一些可用性 订票的例子的话,可能很多人经过几个步骤就不想订了,退出。 如果是悲观的话,其他人都要等他退出,才行。那这个系统应该如何设计? 具体情况具体分析吧,我觉得如果我来设计一个很多人用的系统,我 会用乐观,这样至少可以让大家都不会等太久 【 在 magiczhang 的大作中提到: 】 : 不等待但最后又要回滚,那不是更糟 : 就像你订一张票,你开始以为那张票存在,为了买这张票你花了五分钟填表格,结果.. : 发现票没了,那不是更郁闷? : 反正最后只有第一个提交的事务能提交,那并发还有什么意义呢? ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月15日10:54:09 星期四) 提到: 呵呵,你误解了。我从没说过Serializable和悲观锁是同一个东西。其次,悲观锁不只包 括select...for update这种显示地由程序员指定的锁(而且这种特定于数据库的语句也不 是所有数据库都支持的)。当你把以Serializable的隔离级别启动一个事务的时候,对于 select语句,数据库会干什么呢?它会使用表级别的写锁来排斥其他的读写操作来防止幻 读,这是一个悲观锁。 你所说的read committed级别的悲观锁只是一个读锁(只排斥写操作)。对于我给你的例 子是不能使用的,隔离级别太低,出现的幻读会造成票的重复订购。必须以Serializable 的级别来启动事务,隐式地让数据库使用表级别的排斥读写的锁(高隔离级别的悲观锁) 。在这种情况下,一旦一个事务启动了,使用select了,其他的select就必须阻塞。 最后一点,“事实上一般都是设成read commited”是不对的,事务的隔离级别一定是根据 具体应用来定的。我们之所以采用乐观锁,或者采用你所说的由程序员控制的for update 的read committed级别的锁,都是为了降低隔离级别来加大事务的并行程度,提高perfor mance,使用方法也是要看具体应用的。 【 在 magiczhang 的大作中提到: 】 : 你的概念错了吧。 : 隔离级别设成Serializable和悲观锁是两码事,悲观锁相当于select ... for update : 事实上一般都是设成read commited,然后选择悲观锁或者乐观锁来解决unrepeatabl.. : ad问题 : 事务1 select ... for update的时候 ,事务2光select不加for update是可以的 ☆──────────────────────────────────────☆ quroger (我是来自ROMA的狼·申花情缘) 2008年05月15日11:02:07 星期四 提到: cb好赞~ 【 在 caobo (做一个神,创造奇迹) 的大作中提到: 】 : 呵呵,你误解了。我从没说过Serializable和悲观锁是同一个东西。其次,悲观锁不只包 : 括select...for update这种显示地由程序员指定的锁(而且这种特定于数据库的语句也不 : 是所有数据库都支持的)。当你把以Serializable的隔离级别启动一个事务的时候,对于 : select语句,数据库会干什么呢?它会使用表级别的写锁来排斥其他的读写操作来防止幻 : 读,这是一个悲观锁。 : 你所说的read committed级别的悲观锁只是一个读锁(只排斥写操作)。对于我给你的例 : 子是不能使用的,隔离级别太低,出现的幻读会造成票的重复订购。必须以Serializable : 的级别来启动事务,隐式地让数据库使用表级别的排斥读写的锁(高隔离级别的悲观锁) : 。在这种情况下,一旦一个事务启动了,使用select了,其他的select就必须阻塞。 : 最后一点,“事实上一般都是设成read commited”是不对的,事务的隔离级别一定是根据 : .................(以下省略) ☆──────────────────────────────────────☆ forresty (今天,NIMO了吗?) 2008年05月15日11:34:55 星期四 提到: 神~ 【 在 quroger (我是来自ROMA的狼·申花情缘) 的大作中提到: 】 : cb好赞~ : .................(以下省略) ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月15日12:07:16 星期四) 提到: 那么究竟在什么场景下乐观锁能提高并发效率呢? 如果若干个事务都企图并发修改同一数据,就算能并发访问还是只有一个能提交成功,那 么这种并发性的意义在哪里呢? 【 在 caobo 的大作中提到: 】 : 呵呵,你误解了。我从没说过Serializable和悲观锁是同一个东西。其次,悲观锁不.. : 括select...for update这种显示地由程序员指定的锁(而且这种特定于数据库的语�.. : 是所有数据库都支持的)。当你把以Serializable的隔离级别启动一个事务的时候,.. ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月15日12:22:06 星期四) 提到: 我想还是要看具体应用吧。比如这种情况:若干个事务发生并发冲突的可能性存在,但概 率较小;用乐观锁牺牲一个事务,让它失败并重新执行,来换取大多数事务的并发执行。 【 在 magiczhang 的大作中提到: 】 : 如果若干个事务都企图并发修改同一数据,就算能并发访问还是只有一个能提交成功.. : 么这种并发性的意义在哪里呢? ☆──────────────────────────────────────☆ caobo (做一个神,创造奇迹) 2008年05月15日12:22:45 星期四) 提到: 你们...... 【 在 forresty 的大作中提到: 】 : 神~ ☆──────────────────────────────────────☆ Programmer (要失学了) 2008年05月15日12:31:04 星期四 提到: 我也来拜一下 【 在 forresty (今天,NIMO了吗?) 的大作中提到: 】 : 神~ ☆──────────────────────────────────────☆ forresty (今天,NIMO了吗?) 2008年05月15日12:33:08 星期四 提到: 这么说吧 假设一个表有100条记录,现在有10个事务 乐观锁: 10个事务同时进行,假设2个因为冲突而挂掉,8个事务在1单位时间内完成 悲观锁: 10个事务依次进行,10个事务在10单位时间内完成 不知道有没有理解错误,很是惶恐…… 【 在 magiczhang (梅西,未来之王) 的大作中提到: 】 : 如果若干个事务都企图并发修改同一数据,就算能并发访问还是只有一个能提交成功,那 : 么这种并发性的意义在哪里呢? ☆──────────────────────────────────────☆ forresty (今天,NIMO了吗?) 2008年05月15日12:34:55 星期四 提到: 你推荐他去msra吧。。 【 在 Programmer (要失学了) 的大作中提到: 】 : 我也来拜一下 ☆──────────────────────────────────────☆ Programmer (要失学了) 2008年05月15日12:36:24 星期四 提到: 。。。你是谁 【 在 forresty (今天,NIMO了吗?) 的大作中提到: 】 : 你推荐他去msra吧。。 ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月15日14:53:01 星期四) 提到: 悲观锁不会使10个事务依次进行吧,就算加了锁,只读事务还是可以并发访问的。 而且悲观锁的粒度可以很小,只影响要访问的记录,两个事务依然可以并发访问不同的记 录 但如果要写同一纪录则必须要等待,但是在这种情况下就算用乐观锁也也必然会发生冲突 的 【 在 forresty 的大作中提到: 】 : 这么说吧 : 假设一个表有100条记录,现在有10个事务 : 乐观锁: ☆──────────────────────────────────────☆ magiczhang (梅西,未来之王) 2008年05月15日15:00:08 星期四) 提到: 不对吧,Serializable的粒度太粗了,把整张表都锁住了 Java persistence with hibernate里说: most applications don’t need serializable isolation (phantom reads aren’t usually problematic), and this isolation level tends to scale poorly. Few existing applications use serializable isolation in production, but rather rely on pessimistic locks (see next sections) that effectively force a serial ized execution of operations in certain situations. As you can see, setting the isolation level is a global option that affects a ll connections and transactions. From time to time, it’s useful to specify a more restrictive lock for a particular transaction. Hibernate and Java Persist ence rely on optimistic concurrency control, and both allow you to obtain addi tional locking guarantees with version checking and pessimistic locking. 从这段话可见悲观锁并不包括Serializable 【 在 caobo 的大作中提到: 】 : 呵呵,你误解了。我从没说过Serializable和悲观锁是同一个东西。其次,悲观锁不.. : 括select...for update这种显示地由程序员指定的锁(而且这种特定于数据库的语�.. : 是所有数据库都支持的)。当你把以Serializable的隔离级别启动一个事务的时候,.. : select语句,数据库会干什么呢?它会使用表级别的写锁来排斥其他的读写操作来防.. : 读,这是一个悲观锁。 : 你所说的read committed级别的悲观锁只是一个读锁(只排斥写操作)。对于我给你.. : 子是不能使用的,隔离级别太低,出现的幻读会造成票的重复订购。必须以Serializ.. : 的级别来启动事务,隐式地让数据库使用表级别的排斥读写的锁(高隔离级别的悲观.. : 。在这种情况下,一旦一个事务启动了,使用select了,其他的select就必须阻塞。 : 最后一点,“事实上一般都是设成read commited”是不对的,事务的隔离级别一定�.. : 具体应用来定的。我们之所以采用乐观锁,或者采用你所说的由程序员控制的for up.. : 的read committed级别的锁,都是为了降低隔离级别来加大事务的并行程度,提高pe.. : mance,使用方法也是要看具体应用的。
posted @ 2015-04-07 23:58  奋斗终生  Views(1065)  Comments(0Edit  收藏  举报