这两种锁定形式都会导致进程等待记录的正确副本(如果该记录目前正在由另一个进程使用)。对于悲观锁定,锁机制来自DB本身(本机锁对象),而对于乐观锁定,锁机制是某种形式的行版本控制,如时间戳,用于检查记录是否“陈旧”。
但这两种方法都会导致第二个过程挂起。所以我问:为什么乐观锁定通常被认为比悲观锁定更快/更好?还有,是否有悲观多于乐观的用例?提前感谢!
发布于 2013-03-02 20:00:48
重复问题:
https://stackoverflow.com/questions/129329/optimistic-vs-pessimistic-locking
乐观锁定是一种策略,您可以读取记录,记下版本号,并在写入记录之前检查版本没有更改。当您将记录写回时,您将过滤版本上的更新,以确保它是原子的。(也就是说,在您检查版本并将记录写入磁盘之间没有进行更新),并在一次命中中更新版本。
如果记录是脏的(即与您的记录不同的版本),您将中止事务,用户可以重新启动它。
此策略最适用于大容量系统和三层体系结构,在这些体系结构中,您不一定要为会话维护到数据库的连接。在这种情况下,客户端实际上无法维护数据库锁,因为连接是从池中提取的,而且您可能没有使用从一次访问到下一次访问的相同连接。
悲观锁定是指将记录锁定以供独占使用,直到完成为止。它比乐观锁定具有更好的完整性,但要求您在应用程序设计时小心,以避免死锁。要使用悲观锁定,您需要直接连接到数据库(通常是两层客户端服务器应用程序中的情况),或者需要可以独立于连接使用的外部可用事务ID。
在后一种情况下,您使用TxID打开事务,然后使用该ID重新连接。DBMS维护锁并允许您通过TxID选择会话。这就是使用两阶段提交协议(例如XA或COM+事务)的分布式事务的工作方式。
就性能而言,它取决于您的环境。考虑到下列因素来决定:
在大多数情况下,由于并发性,您会发现乐观会更好。但是,根据RDBMS和环境的不同,这可能会降低或增加性能。通常,通过乐观锁定,您会发现值需要在某个地方进行行版本化。
例如,使用moved,它会被移动到TempDB,在列的末尾会附加12-14字节的内容。打开带有隔离级别(例如快照隔离)的乐观锁定,可能会导致碎片,您的填充因子需要进行调整,因为行的末尾有额外的数据,这可能会导致页面接近满,从而导致页面分割,从而降低性能。如果您的TempDB处于优化状态,那么这将不会那么快。
这些都是我对这件事的看法,更多来自社会人士的意见。
发布于 2013-03-02 23:54:41
你误解了乐观锁定。
乐观锁定不会导致事务等待对方。
乐观锁定可能会导致事务失败,但它这样做时并没有采取任何“锁”。如果事务由于乐观锁定而失败,则要求用户重新启动。“乐观”一词正是源于这样一种期望,即由于这个原因导致交易失败的条件只会在非常特殊的情况下发生。“乐观”锁定是这样一种方法:“我不会去取真正的锁,因为我希望它们无论如何都不会被使用。如果事实证明我错了,我会接受不可避免的失败。”
发布于 2013-03-02 21:05:03
乐观锁定通常更快,因为从数据库的角度来看实际上没有锁定。是否尊重版本列(或伪列,如ora_rowscn)完全取决于应用程序。通常,您有许多应用程序连接到同一个数据库,因此db成为共享资源,如果它挂起,所有客户端都会受到影响。
使用乐观的锁定策略,“挂起”发生在客户端,不会影响其他人。
但是,如果记录经常更新,则可能会重复多次(在乐观锁定的情况下),从而破坏乐观策略的最大好处。
我不同意这两种方法的优越性;这两种方法都可能被滥用。悲观更容易出错,仅仅是因为它更危险:锁定发生在db级别,取决于RDMS,您可能无法控制锁定的内容(锁升级),您需要手动处理锁定顺序。
https://dba.stackexchange.com/questions/35812
复制相似问题