mybatisplus 实现悲观锁
时间: 2024-08-01 21:01:38 浏览: 262
MyBatisPlus是一个基于MyBatis的ORM框架增强工具,它提供了一种简单的方式来处理数据库事务和乐观锁或悲观锁。悲观锁通常是在读取数据时自动获取并锁定记录,直到操作完成并提交事务,防止在此期间其他用户修改数据。
在MyBatisPlus中实现悲观锁,你需要在SQL查询中添加`@Version`注解。`@Version`表示该字段用于版本控制,一般对应数据库中的`version`或`update_time`这样的字段。例如:
```java
// 使用QueryWrapper查询,并开启悲观锁
Integer id = ...; // 要锁定的id
Model model = BaseMapper.selectOne(new QueryWrapper<>(Model.class)
.eq("id", id)
.setLockType(LockType.PESSIMISTIC_WRITE)); // LockType.PESSIMISTIC_WRITE代表悲观锁
// 操作model...
```
在这个例子中,当你尝试更新这个被锁定的数据行时,如果其他线程也在并发地试图更新,那么会抛出`OptimisticLockException`异常,提示数据已由其他事务更改,无法直接更新。
相关问题
mybatisplus的悲观锁和乐观锁定义
### MyBatis Plus 中悲观锁和乐观锁的定义
#### 悲观锁 (Pessimistic Lock)
悲观锁假设每次访问共享资源时都会发生冲突,因此在整个事务过程中锁定该资源。这种方式可以防止其他事务对该资源进行修改,从而保证数据的一致性[^2]。
在数据库层面,可以通过 `SELECT ... FOR UPDATE` 语句来实现悲观锁。当执行这条 SQL 语句时,所查询的数据行会被加锁,直到当前事务结束才会释放这些锁。这期间任何试图读取或写入被锁定记录的操作都将阻塞等待解锁。
```sql
-- 使用 SELECT ... FOR UPDATE 实现悲观锁
SELECT * FROM table_name WHERE id = ? FOR UPDATE;
```
#### 乐观锁 (Optimistic Lock)
相比之下,乐观锁则更加宽松一些。它并不事先对要操作的对象加上排他性的锁,而是允许并发地去尝试更新同一份数据;但在提交更改之前会检查是否有其他进程已经改变了这份数据——如果有,则拒绝此次更新并返回失败给调用者,让其重新获取最新版本后再做相应处理[^3]。
具体到 MyBatis-Plus 的实现方式上,主要是通过引入一个字段(通常命名为 version 或 update_time),每当有新的变更发生在这个实体对象上的时候就自动增加此计数器或者刷新时间戳。这样,在执行更新命令前就能很容易对比服务器端存储着的老版本号与客户端传过来的新版号是否一致了:
```java
@TableField(fill = FieldFill.UPDATE)
private Integer version; // 版本号字段用于支持乐观锁机制
```
MyBatis-Plus 提供了一个内置插件 `OptimisticLockerInnerInterceptor` 来协助完成上述逻辑,使得开发者无需手动编写复杂的业务代码即可轻松集成乐观锁功能[^1]。
mybatisplus悲观锁实现
MyBatis Plus的悲观锁实现方式有两种:
1. 通过select ... for update语句实现悲观锁
```java
// selectForUpdate方法会在查询时加上FOR UPDATE语句,使查询变成悲观锁
User user = userMapper.selectForUpdate(new QueryWrapper<User>().eq("id", 1));
user.setName("newName");
userMapper.updateById(user);
```
2. 通过update ... where ... for update语句实现悲观锁
```java
// update方法会在更新时加上WHERE语句,使更新变成悲观锁
int result = userMapper.update(new User().setName("newName"),
new UpdateWrapper<User>().eq("id", 1).last("FOR UPDATE"));
```
这两种方式的区别在于,第一种方式是在查询时加上FOR UPDATE语句,锁定整个查询结果集,第二种方式是在更新时加上WHERE语句,锁定符合条件的记录。一般来说,第二种方式更加灵活,可以针对需要更新的记录进行锁定,而不是锁定整个查询结果集。
阅读全文
相关推荐


















