悲观锁和乐观锁是什么?谈谈你理解

2 个回答

  • 小王子-B965
    做好自己,至于别人,分交情,看心情。
    ### mysql悲观锁和乐观锁 #### 悲观锁 **概念**: 悲观锁是指对数据库数据的修改持保守态度,在整个数据处理过程中,将数据处于锁定状态,防止被外界(包括本系统的其他事务和外部系统的事务)修改。 **实现**: 悲观锁通常依靠数据库提供的锁机制来实现,因为只有数据库层面的锁机制才能真正保证数据访问的排他性。 **特点**: - **读操作加锁**:读取数据时加锁,防止其他事务修改数据。 - **写操作加锁**:修改或删除数据时加锁,防止其他事务读取或修改数据。 **示例**: ```sql -- 获取悲观锁 SELECT * FROM users WHERE id = 1 FOR UPDATE; -- 其他事务在此行数据上会被阻塞,直到当前事务提交或回滚 ``` **适用场景**: - 数据竞争严重的场景。 - 需要严格保证数据一致性的场景。 #### 乐观锁 **概念**: 乐观锁采取了较宽松的加锁机制,不会在数据处理过程中锁定资源,而是通过在数据更新时检查数据是否被其他事务修改来实现一致性控制。 **实现**: 乐观锁通常基于数据版本(Version)机制实现,即在数据库表中增加一个版本标识字段(如 `version` 字段)。读取数据时将版本号一同读出,更新时对比版本号,如果版本号匹配则更新,否则认为数据已被修改。 **特点**: - **版本控制**:通过版本号控制数据一致性。 - **无需锁定**:在读操作时无需加锁,仅在更新时进行版本号检查。 **示例**: ```sql -- 读取数据和版本号 SELECT id, name, version FROM users WHERE id = 1; -- 更新数据时检查版本号 UPDATE users SET name = 'new_name', version = version + 1 WHERE id = 1 AND version = current_version; -- 如果版本号匹配则更新成功,否则更新失败 ``` **适用场景**: - 数据竞争不严重的场景。 - 需要高并发访问的数据场景。 - 事务较短的场景。 ### 总结 - **悲观锁**: - **特点**:在数据处理过程中加锁,防止并发修改,保证数据的一致性和隔离性。 - **实现**:依靠数据库的锁机制实现,如 `SELECT ... FOR UPDATE`。 - **适用场景**:数据竞争严重,需要严格保证数据一致性的场景。 - **乐观锁**: - **特点**:通过版本控制来实现数据一致性,在更新时检查版本号,不加锁。 - **实现**:基于版本号机制,如通过 `version` 字段控制。 - **适用场景**:数据竞争不严重,需要高并发访问,事务较短的场景。 悲观锁和乐观锁各有优缺点,选择合适的锁机制可以根据具体的应用场景和需求来决定。
    发布于 2023-01-14 18:36 •IP属地 香港
    举报
    评论
    收藏

  • 小菜鸟
    二八佳人体似酥,腰间仗剑斩凡夫。
    **悲观锁** 就是假定在每次取数据的时候会修改这个数据,所以在取数据的时候就会进行加锁,这样其他调用者就不能取数据,阻塞等待,一直到获取到锁。Java中的同步锁sychronized和ReentrantLock就是悲观锁思想的实现。 **乐观锁和悲观锁的区别:** 悲观锁适合多写的场景 乐观锁适合多读的场景,这样只有读写冲突会发生的比较少,减少加锁的性能开销。但是如果是多写的场景,这样会导致上层应用一直重试,增加性能开销。 **乐观锁** 就是假定在每次取数据时不会修改这个数据,所以在取数据的时候不会加锁,只有在真正修改数据时才加锁。Java中的atomic原子变量类就是乐观锁的实现。 **版本号机制** 使用版本号来实现,对数据加上一个版本号,代表修改次数,每次修改后+1,修改数据时判断数据的版本号跟之前取的是否一致,一致才修改,不一致就重试,直到更新成功。 **CAS操作** 就是在更新数据时会传入之前取的值,在内存中判断当前内存中的值跟之前的值是否一致,一致再更新,(比较和更新都是在一个原子操作中)。
    发布于 2022-02-06 11:04 •IP属地 辽宁
    举报
    评论
    收藏