基于 Spring Data JPA 聊聊悲观锁和乐观锁

本文介绍了在多线程、多进程环境下,如何利用Spring Data JPA实现乐观锁和悲观锁来防止数据脏写。乐观锁通过版本号机制确保更新操作的正确性,而悲观锁则利用数据库的行锁或表锁。文章提供两种方式实现乐观锁和悲观锁,并通过测试用例展示了其工作原理。最后,讨论了乐观锁在失败时会抛出异常,而悲观锁中只有一个操作能成功执行。
摘要由CSDN通过智能技术生成

举个场景:多线程、多进程应用在对数据库的同一数据进行非幂等操作时,如果没有添加相应的锁机制进行校验、判断,通常会导致数据的脏写。抛开分布式锁这种解决思路,简单的来讲,可以优先考虑从数据库层面去解决这个问题。

数据库锁分为乐观锁和悲观锁,前者适合读多写少的场景,后者适合读少写多的场景。乐观锁的实现通常是采用加版本号的形式,即如果更新时版本号未发生改变,则本次操作是成功的,且当前版本号的信息也相应会发生改变;再来看看悲观锁,悲观锁的实现方式是在待执行的SQL语句后加上for update,利用了数据库的行锁或是表锁特性来进行实现,但如果使用不当,会严重拖累整个操作的执行速度。

下面的实际案例展示了具体的操作,该项目基于 Spring Data JPA 实现:

  1. 新建两个实体类,Teacher对应悲观锁的示例,User对应乐观锁示例:
/**
 * 悲观锁示例
 */
@Data
@Entity
@NoArgsConstructor
public class Teacher {
   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    public Teacher(String name) {
   
        this.name = name;
    }
}
/**
 * 乐观锁示例
 */
@Data
@Entity
@NoArgsConstructor
public class User {
   

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    /**
     * 乐观锁实现方式①:直接添加@Version
     */
    @Version
    private Integer version = 0;

    public User(String name) {
   
        this.name = name;
    }
}

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值