Commit ebe82383 authored by 高洋's avatar 高洋

Updates 后端开发/lock.md

Auto commit by GitBook Editor
parent bf6acb42
# 锁机制
融租易提供两种锁机制, 满足项目上对数据并发修改的需求.
## 1.数据库锁
***
根据适当的参数进行物理锁定(数据库级锁),支持3种数据库:oracle,mysql,sqlserver。提供 API, 自动执行 sql
>
mysql,orcale 执行 select * from xxx where ... for update
> sqlserver 执行 select * from xxx with (ROWLOCK) where ...
> 都是数据库原生的锁机制
使用方式:
### 单数据源
在Java代码中,注入`DatabaseLockProvider`类,
```java
public class XXXServiceImpl {
@Autowired
private DatabaseLockProvider databaseLockProvider;
public int update (XXX dto, ...){
// 传入锁定对象,锁定数据库相关行
databaseLockProvider.lock(dto);
//...
}
}
```
### 多数据源
在Java代码中,`自己创建DatabaseLockProvider类`,指定`dataSource`
```java
public class XXXServiceImpl {
@Autowired
@Qualifier("xxxDataSource")
private DataSource dataSource;
private DatabaseLockProvider databaseLockProvider;
@Transactional(propagation = Propagation.REQUIRED)
public int update (XXX dto, ...){
databaseLockProvider = new DatabaseLockProvider(dataSource)
// 传入锁定对象,锁定数据库相关行
databaseLockProvider.lock(dto);
//...
}
}
```
> 事务提交以后,锁会自动释放
DatabaseLockProvider提供的接口
```java
//根据传入对象,自动加锁。
//确保bean上有@Table 注解,能自动解析出对应的表。 默认根据有@ID注解的字段进行加锁,确保id有值
public void lock(Object dto)
//根据传入对象和自定义的where条件,自动加锁。
//传入类似 "name = ? and age = ?" 的条件语句,根据whereCondition,依次对应传入属性对应的值。
public void lock(Object dto, String whereCondition, Object... whereParameter)
// 可以自定义表名,不必传入dto
public void lock(String tableName, String whereCondition, Object... whereParameter)
```
## 2.分布式锁
基于`redis`的锁,实现跨平台, 分布式锁
使用方式:
1.根据实际配置的redis,修改配置文件`config.properties`
```properties
redisson.server.url=127.0.0.1:6379
#redissson.server.password=
```
> 支持`多节点`配置,按照如下规范配置
>redisson.server.url=\
> 127.0.0.1:6379,\
> 10.211.103.142:6379
>内部使用redisson提供的`RedLock`进行加锁
2.在java代码中注入DistributedLockProvider
```java
public class XXXServiceImpl {
@Autowired
@Qualifier("distributeLockTemplate")
private DistributedLockProvider distributedLockProvider;
public int update (XXX dto, ...){
//使用回调方式,执行自己的业务逻辑
distributedLockProvider.lock(dto,new DistributedLockCallback<Object>() {
@Override
public Object process() {
//doSomething();
return null;
})
}
}
```
> 回调函数执行以后,锁都会自动释放
DistributedLockProvider提供的接口:
```java
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @return 回调函数返回的内容
*/
<T> T lock(Object lockKey, DistributedLockCallback<T> callback);
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 确保唯一
* @param callback
* @return 回调函数返回的内容
*/
<T> T lock(String lockKey, DistributedLockCallback<T> callback);
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* @return 回调函数返回的内容
*/
<T> T lock(Object lockKey, DistributedLockCallback<T> callback, long leaseTime, TimeUnit timeUnit);
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 确保唯一
* @param callback
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* @return 回调函数返回的内容
*/
<T> T lock(String lockKey, DistributedLockCallback<T> callback, long leaseTime, TimeUnit timeUnit);
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 确保唯一
* @param callback
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<T> T tryLock(String lockKey, DistributedLockCallback<T> callback) throws Exception;
/**
* 使用分布式锁,使用锁默认超时时间。默认等待时间1秒
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<T> T tryLock(Object lockKey, DistributedLockCallback<T> callback) throws Exception;
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @param waitTime
* 获取锁等待时间,超过设置时间未获得锁则抛出异常
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* waitTime,leaseTime 时间单位
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<T> T tryLock(Object lockKey, DistributedLockCallback<T> callback, long waitTime, long leaseTime, TimeUnit timeUnit)
throws Exception;
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 确保唯一
* @param callback
* @param waitTime
* 获取锁等待时间,超过设置时间未获得锁则抛出异常
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* waitTime,leaseTime 的时间单位
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<T> T tryLock(String lockKey, DistributedLockCallback<T> callback, long waitTime, long leaseTime, TimeUnit timeUnit)
throws Exception;
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment