{"id":3688,"date":"2018-10-30T19:16:00","date_gmt":"2018-10-30T11:16:00","guid":{"rendered":"http:\/\/switch.linesno.com\/?p=3688"},"modified":"2018-10-30T19:19:43","modified_gmt":"2018-10-30T11:19:43","slug":"%e5%9f%ba%e4%ba%8eredis%e7%9a%84%e5%88%86%e5%b8%83%e5%bc%8f%e9%94%81","status":"publish","type":"post","link":"http:\/\/switch.linesno.com\/?p=3688","title":{"rendered":"\u57fa\u4e8eRedis\u7684\u5206\u5e03\u5f0f\u9501"},"content":{"rendered":"<div>\n<div>\n<h1>\u5e94\u7528\u573a\u666f<\/h1>\n<p>\u5f53\u591a\u4e2a\u673a\u5668\uff08\u591a\u4e2a\u8fdb\u7a0b\uff09\u4f1a\u5bf9\u540c\u4e00\u6761\u6570\u636e\u8fdb\u884c\u4fee\u6539\u65f6\uff0c\u5e76\u4e14\u8981\u6c42\u8fd9\u4e2a\u4fee\u6539\u662f\u539f\u5b50\u6027\u7684\u3002\u8fd9\u91cc\u6709\u4e24\u4e2a\u9650\u5b9a\uff1a\uff081\uff09\u591a\u4e2a\u8fdb\u7a0b\u4e4b\u95f4\u7684\u7ade\u4e89\uff0c\u610f\u5473\u7740JDK\u81ea\u5e26\u7684\u9501\u5931\u6548\uff1b\uff082\uff09\u539f\u5b50\u6027\u4fee\u6539\uff0c\u610f\u5473\u7740\u6570\u636e\u662f\u6709\u72b6\u6001\u7684\uff0c\u4fee\u6539\u524d\u540e\u6709\u4f9d\u8d56\u3002<\/p>\n<h1>\u5b9e\u73b0\u65b9\u5f0f<\/h1>\n<ul>\n<li>\u57fa\u4e8eRedis\u5b9e\u73b0\uff0c\u4e3b\u8981\u57fa\u4e8eredis\u7684setnx\uff08set if not exist\uff09\u547d\u4ee4\uff1b<\/li>\n<li>\u57fa\u4e8eZookeeper\u5b9e\u73b0\uff1b<\/li>\n<li>\u57fa\u4e8eversion\u5b57\u6bb5\u5b9e\u73b0\uff0c\u4e50\u89c2\u9501\uff0c\u4e24\u4e2a\u7ebf\u7a0b\u53ef\u4ee5\u540c\u65f6\u8bfb\u53d6\u5230\u539f\u6709\u7684version\u503c\uff0c\u4f46\u662f\u6700\u7ec8\u53ea\u6709\u4e00\u4e2a\u53ef\u4ee5\u5b8c\u6210\u64cd\u4f5c\uff1b<\/li>\n<\/ul>\n<p>\u8fd9\u4e09\u79cd\u65b9\u5f0f\u4e2d\uff0c\u6211\u63a5\u89e6\u8fc7\u7b2c\u4e00\u548c\u7b2c\u4e09\u79cd\u3002\u57fa\u4e8eredis\u7684\u5206\u5e03\u5f0f\u9501\u529f\u80fd\u66f4\u52a0\u5f3a\u5927\uff0c\u53ef\u4ee5\u5b9e\u73b0\u963b\u585e\u548c\u975e\u963b\u585e\u9501\u3002<\/p>\n<h1>\u57fa\u4e8eRedis\u7684\u5b9e\u8df5<\/h1>\n<h2>\u9501\u7684\u5b9e\u73b0<\/h2>\n<ul>\n<li>\u9501\u7684key\u4e3a\u76ee\u6807\u6570\u636e\u7684\u552f\u4e00\u952e\uff0cvalue\u4e3a\u9501\u7684\u671f\u671b\u8d85\u65f6\u65f6\u95f4\u70b9\uff1b<\/li>\n<li>\u9996\u5148\u8fdb\u884c\u4e00\u6b21setnx\u547d\u4ee4\uff0c\u5c1d\u8bd5\u83b7\u53d6\u9501\uff0c\u5982\u679c\u83b7\u53d6\u6210\u529f\uff0c\u5219\u8bbe\u7f6e\u9501\u7684\u6700\u7ec8\u8d85\u65f6\u65f6\u95f4\uff08\u4ee5\u9632\u5728\u5f53\u524d\u8fdb\u7a0b\u83b7\u53d6\u9501\u540e\u5954\u6e83\u5bfc\u81f4\u9501\u65e0\u6cd5\u91ca\u653e\uff09\uff1b\u5982\u679c\u83b7\u53d6\u9501\u5931\u8d25\uff0c\u5219\u68c0\u67e5\u5f53\u524d\u7684\u9501\u662f\u5426\u8d85\u65f6\uff0c\u5982\u679c\u53d1\u73b0\u6ca1\u6709\u8d85\u65f6\uff0c\u5219\u83b7\u53d6\u9501\u5931\u8d25\uff1b\u5982\u679c\u53d1\u73b0\u9501\u5df2\u7ecf\u8d85\u65f6\uff08\u5373\u9501\u7684\u8d85\u65f6\u65f6\u95f4\u5c0f\u4e8e\u7b49\u4e8e\u5f53\u524d\u65f6\u95f4\uff09\uff0c\u5219\u518d\u6b21\u5c1d\u8bd5\u83b7\u53d6\u9501\uff0c\u53d6\u5230\u540e\u5224\u65ad\u4e0b\u5f53\u524d\u7684\u8d85\u65f6\u65f6\u95f4\u548c\u4e4b\u524d\u7684\u8d85\u65f6\u65f6\u95f4\u662f\u5426\u76f8\u7b49\uff0c\u5982\u679c\u76f8\u7b49\u5219\u8bf4\u660e\u5f53\u524d\u7684\u5ba2\u6237\u7aef\u662f\u6392\u961f\u7b49\u5f85\u7684\u7ebf\u7a0b\u91cc\u7684\u7b2c\u4e00\u4e2a\u5c1d\u8bd5\u83b7\u53d6\u9501\u7684\uff0c\u8ba9\u5b83\u83b7\u53d6\u6210\u529f\u5373\u53ef\u3002\n<div class=\"image-package\">\n<div class=\"image-container\">\n<div class=\"image-container-fill\"><\/div>\n<div class=\"image-view\" data-width=\"649\" data-height=\"1458\"><img class=\"\" data-original-src=\"\/2018\/10\/8b60bb20c059167e76553047e9ef7484.png\" data-original-width=\"649\" data-original-height=\"1458\" data-original-format=\"image\/png\" data-original-filesize=\"62480\" \/><a href=\"\/2018\/10\/44770-f8c10db8066e44e6.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-3691\" src=\"\/2018\/10\/44770-f8c10db8066e44e6.png\" alt=\"\" width=\"649\" height=\"1458\" \/><\/a><\/div>\n<\/div>\n<div class=\"image-caption\">\u57fa\u4e8eredis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u903b\u8f91.png<\/div>\n<\/div>\n<\/li>\n<\/ul>\n<pre class=\"hljs java\"><code class=\"java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RedisDistributionLock<\/span> <\/span>{\r\n\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Logger logger = LoggerFactory.getLogger(RedisDistributionLock.class);\r\n\r\n    <span class=\"hljs-comment\">\/\/key\u7684TTL,\u4e00\u5929<\/span>\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">int<\/span> finalDefaultTTLwithKey = <span class=\"hljs-number\">24<\/span> * <span class=\"hljs-number\">3600<\/span>;\r\n\r\n    <span class=\"hljs-comment\">\/\/\u9501\u9ed8\u8ba4\u8d85\u65f6\u65f6\u95f4,20\u79d2<\/span>\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">long<\/span> defaultExpireTime = <span class=\"hljs-number\">20<\/span> * <span class=\"hljs-number\">1000<\/span>;\r\n\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">boolean<\/span> Success = <span class=\"hljs-keyword\">true<\/span>;\r\n    \r\n    <span class=\"hljs-meta\">@Resource<\/span>( name = <span class=\"hljs-string\">\"redisTemplate\"<\/span>)\r\n    <span class=\"hljs-keyword\">private<\/span> RedisTemplate&lt;String, String&gt; redisTemplateForGeneralize;\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u52a0\u9501,\u9501\u9ed8\u8ba4\u8d85\u65f6\u65f6\u95f420\u79d2\r\n     * <span class=\"hljs-doctag\">@param<\/span> resource\r\n     * <span class=\"hljs-doctag\">@return<\/span>\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(String resource)<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">this<\/span>.lock(resource, defaultExpireTime);\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u52a0\u9501,\u540c\u65f6\u8bbe\u7f6e\u9501\u8d85\u65f6\u65f6\u95f4\r\n     * <span class=\"hljs-doctag\">@param<\/span> key \u5206\u5e03\u5f0f\u9501\u7684key\r\n     * <span class=\"hljs-doctag\">@param<\/span> expireTime \u5355\u4f4d\u662fms\r\n     * <span class=\"hljs-doctag\">@return<\/span>\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">lock<\/span><span class=\"hljs-params\">(String key, <span class=\"hljs-keyword\">long<\/span> expireTime)<\/span> <\/span>{\r\n\r\n        logger.debug(<span class=\"hljs-string\">\"redis lock debug, start. key:[{}], expireTime:[{}]\"<\/span>,key,expireTime);\r\n        <span class=\"hljs-keyword\">long<\/span> now = Instant.now().toEpochMilli();\r\n        <span class=\"hljs-keyword\">long<\/span> lockExpireTime = now + expireTime;\r\n\r\n        <span class=\"hljs-comment\">\/\/setnx<\/span>\r\n        <span class=\"hljs-keyword\">boolean<\/span> executeResult = redisTemplateForGeneralize.opsForValue().setIfAbsent(key,String.valueOf(lockExpireTime));\r\n        logger.debug(<span class=\"hljs-string\">\"redis lock debug, setnx. key:[{}], expireTime:[{}], executeResult:[{}]\"<\/span>, key, expireTime,executeResult);\r\n\r\n        <span class=\"hljs-comment\">\/\/\u53d6\u9501\u6210\u529f,\u4e3akey\u8bbe\u7f6eexpire<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> (executeResult == Success) {\r\n            redisTemplateForGeneralize.expire(key,finalDefaultTTLwithKey, TimeUnit.SECONDS);\r\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\r\n        }\r\n        <span class=\"hljs-comment\">\/\/\u6ca1\u6709\u53d6\u5230\u9501,\u7ee7\u7eed\u6d41\u7a0b<\/span>\r\n        <span class=\"hljs-keyword\">else<\/span>{\r\n            Object valueFromRedis = <span class=\"hljs-keyword\">this<\/span>.getKeyWithRetry(key, <span class=\"hljs-number\">3<\/span>);\r\n            <span class=\"hljs-comment\">\/\/ \u907f\u514d\u83b7\u53d6\u9501\u5931\u8d25,\u540c\u65f6\u5bf9\u65b9\u91ca\u653e\u9501\u540e,\u9020\u6210NPE<\/span>\r\n            <span class=\"hljs-keyword\">if<\/span> (valueFromRedis != <span class=\"hljs-keyword\">null<\/span>) {\r\n                <span class=\"hljs-comment\">\/\/\u5df2\u5b58\u5728\u7684\u9501\u8d85\u65f6\u65f6\u95f4<\/span>\r\n                <span class=\"hljs-keyword\">long<\/span> oldExpireTime = Long.parseLong((String)valueFromRedis);\r\n                logger.debug(<span class=\"hljs-string\">\"redis lock debug, key already seted. key:[{}], oldExpireTime:[{}]\"<\/span>,key,oldExpireTime);\r\n                <span class=\"hljs-comment\">\/\/\u9501\u8fc7\u671f\u65f6\u95f4\u5c0f\u4e8e\u5f53\u524d\u65f6\u95f4,\u9501\u5df2\u7ecf\u8d85\u65f6,\u91cd\u65b0\u53d6\u9501<\/span>\r\n                <span class=\"hljs-keyword\">if<\/span> (oldExpireTime &lt;= now) {\r\n                    logger.debug(<span class=\"hljs-string\">\"redis lock debug, lock time expired. key:[{}], oldExpireTime:[{}], now:[{}]\"<\/span>, key, oldExpireTime, now);\r\n                    String valueFromRedis2 = redisTemplateForGeneralize.opsForValue().getAndSet(key, String.valueOf(lockExpireTime));\r\n                    <span class=\"hljs-keyword\">long<\/span> currentExpireTime = Long.parseLong(valueFromRedis2);\r\n                    <span class=\"hljs-comment\">\/\/\u5224\u65adcurrentExpireTime\u4e0eoldExpireTime\u662f\u5426\u76f8\u7b49<\/span>\r\n                    <span class=\"hljs-keyword\">if<\/span>(currentExpireTime == oldExpireTime){\r\n                        <span class=\"hljs-comment\">\/\/\u76f8\u7b49,\u5219\u53d6\u9501\u6210\u529f<\/span>\r\n                        logger.debug(<span class=\"hljs-string\">\"redis lock debug, getSet. key:[{}], currentExpireTime:[{}], oldExpireTime:[{}], lockExpireTime:[{}]\"<\/span>, key, currentExpireTime, oldExpireTime, lockExpireTime);\r\n                        redisTemplateForGeneralize.expire(key, finalDefaultTTLwithKey, TimeUnit.SECONDS);\r\n                        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">true<\/span>;\r\n                    }<span class=\"hljs-keyword\">else<\/span>{\r\n                        <span class=\"hljs-comment\">\/\/\u4e0d\u76f8\u7b49,\u53d6\u9501\u5931\u8d25<\/span>\r\n                        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\r\n                    }\r\n                }\r\n            }\r\n            <span class=\"hljs-keyword\">else<\/span> {\r\n                logger.warn(<span class=\"hljs-string\">\"redis lock,lock have been release. key:[{}]\"<\/span>, key);\r\n                <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\r\n            }\r\n        }\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">false<\/span>;\r\n    }\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> Object <span class=\"hljs-title\">getKeyWithRetry<\/span><span class=\"hljs-params\">(String key, <span class=\"hljs-keyword\">int<\/span> retryTimes)<\/span> <\/span>{\r\n        <span class=\"hljs-keyword\">int<\/span> failTime = <span class=\"hljs-number\">0<\/span>;\r\n        <span class=\"hljs-keyword\">while<\/span> (failTime &lt; retryTimes) {\r\n            <span class=\"hljs-keyword\">try<\/span> {\r\n                <span class=\"hljs-keyword\">return<\/span> redisTemplateForGeneralize.opsForValue().get(key);\r\n            } <span class=\"hljs-keyword\">catch<\/span> (Exception e) {\r\n                failTime++;\r\n                <span class=\"hljs-keyword\">if<\/span> (failTime &gt;= retryTimes) {\r\n                    <span class=\"hljs-keyword\">throw<\/span> e;\r\n                }\r\n            }\r\n        }\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">null<\/span>;\r\n    }\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u89e3\u9501\r\n     * <span class=\"hljs-doctag\">@param<\/span> key\r\n     * <span class=\"hljs-doctag\">@return<\/span>\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">unlock<\/span><span class=\"hljs-params\">(String key)<\/span> <\/span>{\r\n        logger.debug(<span class=\"hljs-string\">\"redis unlock debug, start. resource:[{}].\"<\/span>,key);\r\n        redisTemplateForGeneralize.delete(key);\r\n        <span class=\"hljs-keyword\">return<\/span> Success;\r\n    }\r\n}\r\n<\/code><\/pre>\n<h2>\u81ea\u5b9a\u4e49\u6ce8\u89e3\u4f7f\u7528\u5206\u5e03\u5f0f\u9501<\/h2>\n<pre class=\"hljs java\"><code class=\"java\"><span class=\"hljs-meta\">@Retention<\/span>(RetentionPolicy.RUNTIME)\r\n<span class=\"hljs-meta\">@Target<\/span>(ElementType.METHOD)\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-meta\">@interface<\/span> RedisLockAnnoation {\r\n\r\n    <span class=\"hljs-function\">String <span class=\"hljs-title\">keyPrefix<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> \"\"<\/span>;\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u8981\u9501\u5b9a\u7684key\u4e2d\u5305\u542b\u7684\u5c5e\u6027\r\n     *\/<\/span>\r\n    String[] keys() <span class=\"hljs-keyword\">default<\/span> {};\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u662f\u5426\u963b\u585e\u9501\uff1b\r\n     * 1. true\uff1a\u83b7\u53d6\u4e0d\u5230\u9501\uff0c\u963b\u585e\u4e00\u5b9a\u65f6\u95f4\uff1b\r\n     * 2. false\uff1a\u83b7\u53d6\u4e0d\u5230\u9501\uff0c\u7acb\u5373\u8fd4\u56de\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">boolean<\/span> <span class=\"hljs-title\">isSpin<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">true<\/span><\/span>;\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u8d85\u65f6\u65f6\u95f4\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">expireTime<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> 10000<\/span>;\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u7b49\u5f85\u65f6\u95f4\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">waitTime<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> 50<\/span>;\r\n\r\n    <span class=\"hljs-comment\">\/**\r\n     * \u83b7\u53d6\u4e0d\u5230\u9501\u7684\u7b49\u5f85\u65f6\u95f4\r\n     *\/<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">retryTimes<\/span><span class=\"hljs-params\">()<\/span> <span class=\"hljs-keyword\">default<\/span> 20<\/span>;\r\n}\r\n<\/code><\/pre>\n<h2>\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684\u903b\u8f91<\/h2>\n<pre class=\"hljs java\"><code class=\"java\"><span class=\"hljs-meta\">@Component<\/span>\r\n<span class=\"hljs-meta\">@Aspect<\/span>\r\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RedisLockAdvice<\/span> <\/span>{\r\n\r\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> Logger logger = LoggerFactory.getLogger(RedisLockAdvice.class);\r\n\r\n    <span class=\"hljs-meta\">@Resource<\/span>\r\n    <span class=\"hljs-keyword\">private<\/span> RedisDistributionLock redisDistributionLock;\r\n\r\n    <span class=\"hljs-meta\">@Around<\/span>(<span class=\"hljs-string\">\"@annotation(RedisLockAnnoation)\"<\/span>)\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> Object <span class=\"hljs-title\">processAround<\/span><span class=\"hljs-params\">(ProceedingJoinPoint pjp)<\/span> <span class=\"hljs-keyword\">throws<\/span> Throwable <\/span>{\r\n        <span class=\"hljs-comment\">\/\/\u83b7\u53d6\u65b9\u6cd5\u4e0a\u7684\u6ce8\u89e3\u5bf9\u8c61<\/span>\r\n        String methodName = pjp.getSignature().getName();\r\n        Class&lt;?&gt; classTarget = pjp.getTarget().getClass();\r\n        Class&lt;?&gt;[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();\r\n        Method objMethod = classTarget.getMethod(methodName, par);\r\n        RedisLockAnnoation redisLockAnnoation = objMethod.getDeclaredAnnotation(RedisLockAnnoation.class);\r\n\r\n        <span class=\"hljs-comment\">\/\/\u62fc\u88c5\u5206\u5e03\u5f0f\u9501\u7684key<\/span>\r\n        String[] keys = redisLockAnnoation.keys();\r\n        Object[] args = pjp.getArgs();\r\n        Object arg = args[<span class=\"hljs-number\">0<\/span>];\r\n        StringBuilder temp = <span class=\"hljs-keyword\">new<\/span> StringBuilder();\r\n        temp.append(redisLockAnnoation.keyPrefix());\r\n        <span class=\"hljs-keyword\">for<\/span> (String key : keys) {\r\n            String getMethod = <span class=\"hljs-string\">\"get\"<\/span> + StringUtils.capitalize(key);\r\n            temp.append(MethodUtils.invokeExactMethod(arg, getMethod)).append(<span class=\"hljs-string\">\"_\"<\/span>);\r\n        }\r\n        String redisKey = StringUtils.removeEnd(temp.toString(), <span class=\"hljs-string\">\"_\"<\/span>);\r\n\r\n        <span class=\"hljs-comment\">\/\/\u6267\u884c\u5206\u5e03\u5f0f\u9501\u7684\u903b\u8f91<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> (redisLockAnnoation.isSpin()) {\r\n            <span class=\"hljs-comment\">\/\/\u963b\u585e\u9501<\/span>\r\n            <span class=\"hljs-keyword\">int<\/span> lockRetryTime = <span class=\"hljs-number\">0<\/span>;\r\n            <span class=\"hljs-keyword\">try<\/span> {\r\n                <span class=\"hljs-keyword\">while<\/span> (!redisDistributionLock.lock(redisKey, redisLockAnnoation.expireTime())) {\r\n                    <span class=\"hljs-keyword\">if<\/span> (lockRetryTime++ &gt; redisLockAnnoation.retryTimes()) {\r\n                        logger.error(<span class=\"hljs-string\">\"lock exception. key:{}, lockRetryTime:{}\"<\/span>, redisKey, lockRetryTime);\r\n                        <span class=\"hljs-keyword\">throw<\/span> ExceptionUtil.geneException(CommonExceptionEnum.SYSTEM_ERROR);\r\n                    }\r\n                    ThreadUtil.holdXms(redisLockAnnoation.waitTime());\r\n                }\r\n                <span class=\"hljs-keyword\">return<\/span> pjp.proceed();\r\n            } <span class=\"hljs-keyword\">finally<\/span> {\r\n                redisDistributionLock.unlock(redisKey);\r\n            }\r\n        } <span class=\"hljs-keyword\">else<\/span> {\r\n            <span class=\"hljs-comment\">\/\/\u975e\u963b\u585e\u9501<\/span>\r\n            <span class=\"hljs-keyword\">try<\/span> {\r\n                <span class=\"hljs-keyword\">if<\/span> (!redisDistributionLock.lock(redisKey)) {\r\n                    logger.error(<span class=\"hljs-string\">\"lock exception. key:{}\"<\/span>, redisKey);\r\n                    <span class=\"hljs-keyword\">throw<\/span> ExceptionUtil.geneException(CommonExceptionEnum.SYSTEM_ERROR);\r\n                }\r\n                <span class=\"hljs-keyword\">return<\/span> pjp.proceed();\r\n            } <span class=\"hljs-keyword\">finally<\/span> {\r\n                redisDistributionLock.unlock(redisKey);\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n<p><audio style=\"display: none;\" controls=\"controls\"><\/audio><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5e94\u7528\u573a\u666f \u5f53\u591a\u4e2a\u673a\u5668\uff08\u591a\u4e2a\u8fdb\u7a0b\uff09\u4f1a\u5bf9\u540c\u4e00\u6761\u6570\u636e\u8fdb\u884c\u4fee\u6539\u65f6\uff0c\u5e76\u4e14\u8981\u6c42\u8fd9\u4e2a\u4fee\u6539\u662f\u539f\u5b50\u6027\u7684\u3002\u8fd9\u91cc\u6709\u4e24\u4e2a\u9650\u5b9a\uff1a\uff081\uff09\u591a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[86,7],"tags":[],"class_list":["post-3688","post","type-post","status-publish","format-standard","hentry","category-service","category-day"],"_links":{"self":[{"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/posts\/3688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3688"}],"version-history":[{"count":3,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/posts\/3688\/revisions"}],"predecessor-version":[{"id":3694,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=\/wp\/v2\/posts\/3688\/revisions\/3694"}],"wp:attachment":[{"href":"http:\/\/switch.linesno.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3688"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/switch.linesno.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}