spring項目對某條單據(jù)進行加鎖處理的方法
最近工作中有個對工單單據(jù)進行加鎖/解鎖處理,目的是為了防止多用戶對同一條單據(jù)處理。以下是完整的前后端代碼。
前端JS billLock.js
let orderLock = { orderLock:(viewmodel, id, billType)=>{ var url = '/orderLock/lock?domainKey='+viewmodel.getDomainKey(); var proxy = cb.rest.DynamicProxy.create({ ensure: {url: url, method: 'POST'} }); let data = {"id":id, "billType": billType, "ttl": 60*60*12} proxy.ensure(data, function (err, result) { if (err) { cb.utils.alert(err.message, 'error'); } else { cb.utils.alert(result, 'info'); if(viewmodel.originalViewMeta.cBillNo && viewmodel.originalViewMeta.cBillNo=="02924ed1"){ //維修領料頁面進入 if(result.indexOf('成功') <= 0){ viewmodel.biz.action().common.browse(viewmodel) viewmodel.biz.action().common.setMode(viewmodel,"browse"); } }else{ if(result.indexOf('成功') <= 0){ viewmodel.biz.action().common.browse(viewmodel) } } } }) }, unOrderLock:(viewmodel, id, billType)=>{ var url = '/orderLock/unLock?domainKey='+viewmodel.getDomainKey(); var proxy = cb.rest.DynamicProxy.create({ ensure: {url: url, method: 'POST'} }); var data = {"id":id, "billType": billType} proxy.ensure(data, function (err, result) { if (err) { cb.utils.alert(err.message, 'error'); } else { cb.utils.alert(result, 'info'); } }) } } export default orderLock
后端Java 代碼
@RestController @RequestMapping("/orderLock") @Slf4j public class OrderLockController extends BaseController { @Autowired private GmsRedisUtil gmsRRedisUtil; @Autowired private UserInfoService userInfoService; private String ENGINE_NO = "afterservice"; /** * 加鎖 */ @PostMapping(value = "/lock") public void orderLock(@RequestBody OrderLockDTO orderLockDTO, HttpServletResponse response) { try{ String result; UserExtendDto userExtendDto = userInfoService.getUserExtend(); String nowDate = DateUtil.dateFormat(PartCommonConstants.dateTimeFormatter, LocalDateTime.now()); String key = ENGINE_NO + "_" + orderLockDTO.getBillType() + "_" + orderLockDTO.getId(); String message = "鎖定人["+userExtendDto.getStaffName()+"]鎖定時間["+nowDate+"]"; Boolean flag = gmsRRedisUtil.tryGetLock(key, message, orderLockDTO.getTtl(), 2); if(flag){ result = "加鎖成功!"; }else{ String lockValue = gmsRRedisUtil.getObject(key); if(lockValue.contains(userExtendDto.getStaffName())){ result = "加鎖成功!原鎖定用戶["+userExtendDto.getStaffName()+"]進入單據(jù)!"; }else{ result = "加鎖失敗!單據(jù)已被鎖定,"+lockValue; } } renderJson(response, ResultMessage.data(result,false)); }catch(Exception e){ renderJson(response, ResultMessage.error(e.getMessage())); log.error("加鎖失敗:{}",e); } }
代碼解析(以上代碼大致步驟如下:)
1. 前端代碼 參數(shù)是data,帶有id,billtype,字符串ttl,時間變量 4個參數(shù)穿入后端。
2.后端接收參數(shù),調(diào)用gmsRRedisUtil.tryGetLock,這個方法是項目框架自己封裝,原理是實現(xiàn)了redisTemplate.opsForValue().setIfAbsent方法
3.setIfAbsent方法簡單介紹如下:
1.setIfAbsent(K var1, V var2); 如果key不存在則新增,key存在不做任何操作 redisTemplate.opsForValue().setIfAbsent("BBB", "好的"); 2.setIfAbsent(K var1, V var2, long var3, TimeUnit var5) 如果key不存在則新增,同時設置過期時間,key存在不做任何操作。 redisTemplate.opsForValue().setIfAbsent("AAA", "好的", 1, TimeUnit.MINUTES); 3.setIfAbsent(K key, V value, Duration timeout) 如果key不存在則新增,同時設置過期時間,key存在不做任何操作。 redisTemplate.opsForValue().setIfAbsent("BBB", "好的", Duration.ofMinutes(1));
4.如果單據(jù)第一次進入,key不存在,flag為true,直接返回給前端“加鎖成功”,前端解析字符串中含有“成功,不設置頁面為瀏覽態(tài),仍為編輯態(tài)
本次加鎖我調(diào)用的是第2個方法,這里的第一個參數(shù)key可見是單據(jù)id加一些特定字符。所以單據(jù)id就會被加鎖,并設置加鎖時間\
5 如果單據(jù)在已經(jīng)加鎖的情況下,仍有其他用戶編輯此單據(jù),則key重復,gmsRRedisUtil.tryGetLock不做操作。
gmsRRedisUtil.getObject(key)實際是調(diào)用redisTemplate.opsForValue().get(key) 方法,
其中 get(Object var1) 是獲取指定的key對應的值。
第一次加鎖的message是用戶信息,這里如果是不同用戶登錄的話,
if(lockValue.contains(userExtendDto.getStaffName())) 就為false,返回給前端的信息是“加鎖失敗...”,
前端獲取字符串信息中沒有加鎖成功,會設置頁面為瀏覽態(tài),不能編輯。 到此,加鎖完成!
總結(jié)
到此這篇關于spring項目對某條單據(jù)進行加鎖處理的文章就介紹到這了,更多相關spring某條單據(jù)加鎖處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
javaweb前端向后端傳值的幾種方式總結(jié)(附代碼)
javaweb是java開發(fā)中的一個方向,下面這篇文章主要給大家介紹了關于javaweb前端向后端傳值的幾種方式的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-03-03Java實現(xiàn)通過IP獲取IP歸屬地的方法(離線+在線)
我們都知道安全攻擊都是在某臺客戶機上執(zhí)行某些惡意操作致使服務端響應異常崩潰亦或響應數(shù)據(jù)被篡改,首先我想到的是對訪問的web端做一個IP的校驗,那么我們首先得知道客戶端的IP是多少,接下來此文重點介紹如何獲得,需要的朋友可以參考下2023-10-10Java實現(xiàn)經(jīng)典捕魚達人游戲的示例代碼
《捕魚達人》是一款以深海狩獵為題材的休閑競技游戲。本文將利用Java實現(xiàn)這一經(jīng)典的游戲,文中采用了swing技術(shù)進行了界面化處理,需要的可以參考一下2022-02-02java中使用session監(jiān)聽實現(xiàn)同帳號登錄限制、登錄人數(shù)限制
本文主要介紹了java中使用session監(jiān)聽實現(xiàn)同帳號登錄限制、登錄人數(shù)限制,通過session來監(jiān)聽在線人數(shù)和登陸限制,有需要的童鞋可以了解一下。2016-10-10java實現(xiàn)大文件導出的實現(xiàn)與優(yōu)化
這篇文章主要為大家詳細介紹了java實現(xiàn)大文件導出的實現(xiàn)與優(yōu)化的相關資料,文中的示例代碼講解詳細,對我們深入了解java有一定的幫助,感興趣的小伙伴可以了解下2023-11-11