业务锁
在处理并发问题时,很多情况下需要用到业务锁来达到按照某个维度同步执行业务块。
例子:
@Override
@Transactional(rollbackFor = Exception.class, noRollbackFor = TerminateException.class)
public ApplyDO submitApply(ApplyDOapplyDO) {
LockResultEnum lockResultEnum =null;
String lockName = new StringBuffer().append(applyDO.getSite()).append("_").append(applyDO.getSiteMemId()).toString();
try {
//加锁
lockResultEnum = lockManager.getLock(lockName, LockTypeEnum.APPLY_LOCK.getCode());
if (LockResultEnum.没有获取到锁.equals(lockResultEnum)){
throw new BizException(ErrorCode.LOCK_FAIL);
}
…
returnapplyDO;
} catch (TerminateExceptione) {
throwe;
} catch (BizExceptione) {
throw new BizException(e.getErrorCode(),e);
} catch (Exceptione) {
throw new BizException(ErrorCode.GENERIC_ERROR,e);
} finally {
//释放锁
lockManager.releaseLock(lockName, LockTypeEnum.APPLY_LOCK.getCode(),lockResultEnum);
}
}
LockManager的getLock方法实现如下:
@Override
public LockResultEnum getLock(StringlockName,StringlockType){
if(StringUtil.isEmpty(lockName)){
LOG.error("getLock()参数为空,param:" +lockName);
throw new BizException(ErrorCode.ILLEGAL_ARGUMENT,"参数为空!");
}
//只是生成一个数据库锁名,纯粹的字符串拼接过程
String lockName_ = getDBLockName(lockName,lockType);
booleanisGetDbLocked =lockDao.getDbLock(lockName_);
if (isGetDbLocked) {
LockDO lock = lockDao.getRowLockByName(lockName);
if (lock !=null){
return LockResultEnum.获取锁成功;
} else {
return LockResultEnum.仅数据库锁;
}
} else {
LOG.warn("获取锁【" +lockName_+"】失败");
return LockResultEnum.没有获取到锁;
}
}
LockManager的releaseLock方法实现如下:
@Override
public void releaseLock(St