spring項(xiàng)目對某條單據(jù)進(jìn)行加鎖處理的方法
最近工作中有個對工單單據(jù)進(jìn)行加鎖/解鎖處理,目的是為了防止多用戶對同一條單據(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"){ //維修領(lǐng)料頁面進(jìn)入 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ìn)入單據(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àng)目框架自己封裝,原理是實(shí)現(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不存在則新增,同時設(shè)置過期時間,key存在不做任何操作。 redisTemplate.opsForValue().setIfAbsent("AAA", "好的", 1, TimeUnit.MINUTES); 3.setIfAbsent(K key, V value, Duration timeout) 如果key不存在則新增,同時設(shè)置過期時間,key存在不做任何操作。 redisTemplate.opsForValue().setIfAbsent("BBB", "好的", Duration.ofMinutes(1));
4.如果單據(jù)第一次進(jìn)入,key不存在,flag為true,直接返回給前端“加鎖成功”,前端解析字符串中含有“成功,不設(shè)置頁面為瀏覽態(tài),仍為編輯態(tài)
本次加鎖我調(diào)用的是第2個方法,這里的第一個參數(shù)key可見是單據(jù)id加一些特定字符。所以單據(jù)id就會被加鎖,并設(shè)置加鎖時間\
5 如果單據(jù)在已經(jīng)加鎖的情況下,仍有其他用戶編輯此單據(jù),則key重復(fù),gmsRRedisUtil.tryGetLock不做操作。
gmsRRedisUtil.getObject(key)實(shí)際是調(diào)用redisTemplate.opsForValue().get(key) 方法,
其中 get(Object var1) 是獲取指定的key對應(yīng)的值。
第一次加鎖的message是用戶信息,這里如果是不同用戶登錄的話,
if(lockValue.contains(userExtendDto.getStaffName())) 就為false,返回給前端的信息是“加鎖失敗...”,
前端獲取字符串信息中沒有加鎖成功,會設(shè)置頁面為瀏覽態(tài),不能編輯。 到此,加鎖完成!
總結(jié)
到此這篇關(guān)于spring項(xiàng)目對某條單據(jù)進(jìn)行加鎖處理的文章就介紹到這了,更多相關(guān)spring某條單據(jù)加鎖處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java經(jīng)典設(shè)計模式之責(zé)任鏈模式原理與用法詳解
這篇文章主要介紹了Java經(jīng)典設(shè)計模式之責(zé)任鏈模式,簡單說明了責(zé)任鏈模式的概念、原理,并結(jié)合實(shí)例形式分析了java實(shí)現(xiàn)責(zé)任鏈模式的具體用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-08-08javaweb前端向后端傳值的幾種方式總結(jié)(附代碼)
javaweb是java開發(fā)中的一個方向,下面這篇文章主要給大家介紹了關(guān)于javaweb前端向后端傳值的幾種方式的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Java實(shí)現(xiàn)通過IP獲取IP歸屬地的方法(離線+在線)
我們都知道安全攻擊都是在某臺客戶機(jī)上執(zhí)行某些惡意操作致使服務(wù)端響應(yīng)異常崩潰亦或響應(yīng)數(shù)據(jù)被篡改,首先我想到的是對訪問的web端做一個IP的校驗(yàn),那么我們首先得知道客戶端的IP是多少,接下來此文重點(diǎn)介紹如何獲得,需要的朋友可以參考下2023-10-10Java實(shí)現(xiàn)經(jīng)典捕魚達(dá)人游戲的示例代碼
《捕魚達(dá)人》是一款以深海狩獵為題材的休閑競技游戲。本文將利用Java實(shí)現(xiàn)這一經(jīng)典的游戲,文中采用了swing技術(shù)進(jìn)行了界面化處理,需要的可以參考一下2022-02-02java中使用session監(jiān)聽實(shí)現(xiàn)同帳號登錄限制、登錄人數(shù)限制
本文主要介紹了java中使用session監(jiān)聽實(shí)現(xiàn)同帳號登錄限制、登錄人數(shù)限制,通過session來監(jiān)聽在線人數(shù)和登陸限制,有需要的童鞋可以了解一下。2016-10-10java實(shí)現(xiàn)大文件導(dǎo)出的實(shí)現(xiàn)與優(yōu)化
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)大文件導(dǎo)出的實(shí)現(xiàn)與優(yōu)化的相關(guān)資料,文中的示例代碼講解詳細(xì),對我們深入了解java有一定的幫助,感興趣的小伙伴可以了解下2023-11-11