Hibernate 樂觀鎖異常處理
最進在工作中遇到了hibernate 處理併發問題,總結了一下用到了遞迴處理迴圈遞迴嘗試,請大家多多指教
/**
* 判斷產品額度是否可用
* @return
*/
public String isAvailableProductLimit(ProductLimit ccsProductLimit,Date date,BigDecimal txnAmt){
try{
logger.info("額度判斷====isAvailableProductLimit");
//子產品程式碼
String productCodeChildren = ccsProductLimit.getProductCodeChildren();
BigDecimal limitTxnAmt = ccsProductLimit.getLimitTxnAmt();
//服務開始時間
String serviceStartTime = ccsProductLimit.getServiceStartTime();
//服務結束時間
String serviceEndTime = ccsProductLimit.getServiceEndTime();
//判斷是否合法的交易時間
boolean txnBoolean = DateUtils.isInDate(Calendar.getInstance().getTime(), serviceStartTime,serviceEndTime);
//合法
if(txnBoolean){
//獲取產品使用額度
ProductLimitUsing ccsProductLimitUsing = ccsProductLimitService.checkCcsProductLimitUsingExits(ccsProductLimit,date);
//產品額度-使用額度
if(limitTxnAmt.compareTo(ccsProductLimitUsing.getTxnAmtUsing().add(txnAmt)) >=0){
return Constants.TXN_MESSAGE_SUCCESS;
}else{
return Constants.TXN_MESSAGE_NO_LIMIT;
}
2.
}else{
//不合法
return Constants.TXN_MESSAGE_UNOPEN;
}
}catch(Exception e){
if(e instanceof HibernateOptimisticLockingFailureException || e instanceof StaleObjectStateException || e instanceof TransactionSystemException){
//樂觀鎖重試
return isAvailableProductLimit( ccsProductLimit,date,txnAmt);
}else{
e.printStackTrace();
return Constants.TXN_MESSAGE_ERROR;
}
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public CcsProductLimitUsing checkCcsProductLimitUsingExits(ProductLimit ccsProductLimit,Date date){
logger.info("額度判斷====checkCcsProductLimitUsingExits");
QCcsProductLimitUsing qCcsProductLimitUsing = QCcsProductLimitUsing.ccsProductLimitUsing;
JPAQuery query = new JPAQuery(em);
ProductLimitUsing ccsProductLimitUsing = query.from(qCcsProductLimitUsing).where(qCcsProductLimitUsing.productCodeChildren.eq(ccsProductLimit.getProductCodeChildren()).and(qCcsProductLimitUsing.txnEffectiveTime.eq(date))).uniqueResult(qCcsProductLimitUsing);
if(null == ccsProductLimitUsing){
try{
ccsProductLimitUsing = new CcsProductLimitUsing();
ccsProductLimitUsing.setTxnEffectiveTime(date);
ccsProductLimitUsing.setProductCodeChildren(ccsProductLimit.getProductCodeChildren());
ccsProductLimitUsing.setTxnAmtUsing(BigDecimal.ZERO);
ccsProductLimitUsing.setUpdatedTime(new Date());
return rCcsProductLimitUsing.saveAndFlush(ccsProductLimitUsing);
}catch(Exception e){
e.printStackTrace();
//處理唯一性索引異常
checkCcsProductLimitUsingExits(ccsProductLimit,date);
}
}
logger.info("checkCcsProductLimitUsingExits===產品程式碼:{}===時間:{}==ccsProductLimit={}",ccsProductLimit.getProductCodeChildren(),date, JsonSerializeUtil.jsonSerializer(ccsProductLimitUsing));
return ccsProductLimitUsing;
}