Showing
7 changed files
with
311 additions
and
92 deletions
1 | -package com.yohoufo.common.cache; | ||
2 | - | ||
3 | -import com.google.common.collect.Lists; | ||
4 | -import com.yoho.core.redis.cluster.annotation.Redis; | ||
5 | -import com.yoho.core.redis.cluster.operations.nosync.YHRedisTemplate; | ||
6 | -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; | ||
7 | -import lombok.extern.slf4j.Slf4j; | ||
8 | -import org.springframework.data.redis.core.script.DefaultRedisScript; | ||
9 | -import org.springframework.data.redis.core.script.RedisScript; | ||
10 | -import org.springframework.stereotype.Service; | ||
11 | - | ||
12 | -import java.util.concurrent.TimeUnit; | ||
13 | - | ||
14 | -@Service | ||
15 | -@Slf4j | ||
16 | -public class RedisLock { | ||
17 | - | ||
18 | - private static final Long RELEASE_SUCCESS = 1L; | ||
19 | - | ||
20 | - private static final String ACQUIRE_SUCCESS = "OK"; | ||
21 | - | ||
22 | - @Redis("gwNoSyncRedis") | ||
23 | - private YHRedisTemplate redis; | ||
24 | - | ||
25 | - public boolean acquire(RedisKeyBuilder keyBuilder, String value, final long timeout, final TimeUnit unit) { | ||
26 | - try { | ||
27 | - String script = "return redis.call('SET', KEYS[1], ARGV[1], 'NX', 'PX', ARGV[2]) "; | ||
28 | - RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); | ||
29 | - String key = keyBuilder.getKey(); | ||
30 | - String result = redis.getStringRedisTemplate().execute(redisScript, Lists.newArrayList(key), | ||
31 | - value, String.valueOf(unit.toMillis(timeout))); | ||
32 | - return ACQUIRE_SUCCESS.equals(result); | ||
33 | - } catch (Exception e) { | ||
34 | - return false; | ||
35 | - } | ||
36 | - } | ||
37 | - | ||
38 | - public void release(RedisKeyBuilder key, String value) { | ||
39 | - try { | ||
40 | - deleteKeyIfValueEquals(key, value); | ||
41 | - } catch (Exception e) { | ||
42 | - try { | ||
43 | - deleteKeyIfValueEquals(key, value); | ||
44 | - } catch (Exception e1) { | ||
45 | - log.warn("release lock fail, key is {} value is {}", key, value); | ||
46 | - } | ||
47 | - } | ||
48 | - } | ||
49 | - | ||
50 | - private boolean deleteKeyIfValueEquals(RedisKeyBuilder keyBuilder, String value) { | ||
51 | - String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; | ||
52 | - RedisScript<Long> redisScript = new DefaultRedisScript(script, Long.class); | ||
53 | - String key = keyBuilder.getKey(); | ||
54 | - Long result = redis.getStringRedisTemplate().execute(redisScript, Lists.newArrayList(key), value); | ||
55 | - if (RELEASE_SUCCESS.equals(result)) { | ||
56 | - log.info("release lock ok, key is {} value is {}", key, value); | ||
57 | - return true; | ||
58 | - } else { | ||
59 | - log.info("release lock ko, key is {} value is {}", key, value); | ||
60 | - return false; | ||
61 | - } | ||
62 | - } | ||
63 | - | ||
64 | - | ||
65 | -} |
1 | +package com.yohoufo.common.lock; | ||
2 | + | ||
3 | +import com.google.common.collect.Lists; | ||
4 | +import lombok.extern.slf4j.Slf4j; | ||
5 | +import org.springframework.data.redis.core.RedisTemplate; | ||
6 | +import org.springframework.data.redis.core.script.DefaultRedisScript; | ||
7 | +import org.springframework.data.redis.core.script.RedisScript; | ||
8 | + | ||
9 | +import java.util.Random; | ||
10 | +import java.util.UUID; | ||
11 | +import java.util.concurrent.TimeUnit; | ||
12 | + | ||
13 | +/** | ||
14 | + * Redis分布式锁 | ||
15 | + * 使用 SET resource-name anystring NX EX max-lock-time 实现 | ||
16 | + * <p> | ||
17 | + * 该方案在 Redis 官方 SET 命令页有详细介绍。 | ||
18 | + * http://doc.redisfans.com/string/set.html | ||
19 | + * <p> | ||
20 | + * 在介绍该分布式锁设计之前,我们先来看一下在从 Redis 2.6.12 开始 SET 提供的新特性, | ||
21 | + * 命令 SET key value [EX seconds] [PX milliseconds] [NX|XX],其中: | ||
22 | + * <p> | ||
23 | + * EX seconds — 以秒为单位设置 key 的过期时间; | ||
24 | + * PX milliseconds — 以毫秒为单位设置 key 的过期时间; | ||
25 | + * NX — 将key 的值设为value ,当且仅当key 不存在,等效于 SETNX。 | ||
26 | + * XX — 将key 的值设为value ,当且仅当key 存在,等效于 SETEX。 | ||
27 | + * <p> | ||
28 | + * 命令 SET resource-name anystring NX EX max-lock-time 是一种在 Redis 中实现锁的简单方法。 | ||
29 | + * <p> | ||
30 | + * 客户端执行以上的命令: | ||
31 | + * <p> | ||
32 | + * 如果服务器返回 OK ,那么这个客户端获得锁。 | ||
33 | + * 如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。 | ||
34 | + */ | ||
35 | +@Slf4j | ||
36 | +class DefaultRedisLock implements RedisLock { | ||
37 | + | ||
38 | + private static final String ACQUIRE_OK = "OK"; | ||
39 | + | ||
40 | + private static final Long RELEASE_OK = 1L; | ||
41 | + | ||
42 | + private RedisTemplate<String, String> redisTemplate; | ||
43 | + | ||
44 | + private String key; | ||
45 | + | ||
46 | + /** | ||
47 | + * 锁的有效时间(s) | ||
48 | + */ | ||
49 | + private long expireTimeMillis; | ||
50 | + | ||
51 | + /** | ||
52 | + * lua script | ||
53 | + */ | ||
54 | + private String lockValue; | ||
55 | + | ||
56 | + /** | ||
57 | + * 锁标记 | ||
58 | + */ | ||
59 | + private boolean locked; | ||
60 | + | ||
61 | + final Random random = new Random(); | ||
62 | + | ||
63 | + DefaultRedisLock(Builder builder) { | ||
64 | + this.redisTemplate = builder.redisTemplate; | ||
65 | + this.key = builder.key; | ||
66 | + this.expireTimeMillis = builder.expireTimeMillis; | ||
67 | + } | ||
68 | + | ||
69 | + public boolean lock() { | ||
70 | + updateLockValue(); | ||
71 | + while (true) { | ||
72 | + if (acquire(lockValue, expireTimeMillis)) { | ||
73 | + locked = true; | ||
74 | + return true; | ||
75 | + } | ||
76 | + sleep(10, 50000); | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
80 | + public boolean lock(long timeout, TimeUnit timeUnit) { | ||
81 | + updateLockValue(); | ||
82 | + // 请求锁超时时间,纳秒 | ||
83 | + long timeoutNanos = timeUnit.toNanos(timeout); | ||
84 | + // 系统当前时间,纳秒 | ||
85 | + long nowNanoTime = System.nanoTime(); | ||
86 | + while ((System.nanoTime() - nowNanoTime) < timeoutNanos) { | ||
87 | + if (acquire(lockValue, expireTimeMillis)) { | ||
88 | + locked = true; | ||
89 | + // 上锁成功结束请求 | ||
90 | + return true; | ||
91 | + } | ||
92 | + // 每次请求等待一段时间 | ||
93 | + sleep(10, 50000); | ||
94 | + } | ||
95 | + return locked; | ||
96 | + } | ||
97 | + | ||
98 | + public boolean tryLock() { | ||
99 | + updateLockValue(); | ||
100 | + locked = acquireOr(lockValue, expireTimeMillis, false); | ||
101 | + return locked; | ||
102 | + } | ||
103 | + | ||
104 | + public boolean unlock() { | ||
105 | + if (locked) { | ||
106 | + if (releaseOr(lockValue, false)) { | ||
107 | + locked = false; | ||
108 | + return true; | ||
109 | + } else { | ||
110 | + return false; | ||
111 | + } | ||
112 | + } | ||
113 | + return true; | ||
114 | + } | ||
115 | + | ||
116 | + private boolean acquire(String value, long expireTimeMillis) { | ||
117 | + String script = "return redis.call('SET', KEYS[1], ARGV[1], 'NX', 'PX', ARGV[2]) "; | ||
118 | + RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); | ||
119 | + String result = redisTemplate.execute(redisScript, Lists.newArrayList(key), value, String.valueOf(expireTimeMillis)); | ||
120 | + if (ACQUIRE_OK.equals(result)) { | ||
121 | + log.info("acquire lock ok, key is {} value is {}", key, value); | ||
122 | + return true; | ||
123 | + } else { | ||
124 | + log.info("acquire lock ko, key is {} value is {}", key, value); | ||
125 | + return false; | ||
126 | + } | ||
127 | + } | ||
128 | + | ||
129 | + private boolean acquireOr(String value, long expireTimeMillis, boolean defaultValue) { | ||
130 | + try { | ||
131 | + return acquire(value, expireTimeMillis); | ||
132 | + } catch (Exception e) { | ||
133 | + log.info("release lock ko, key is {} value is {}", key, value, e); | ||
134 | + return defaultValue; | ||
135 | + } | ||
136 | + } | ||
137 | + | ||
138 | + private boolean release(String value) { | ||
139 | + String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; | ||
140 | + RedisScript<Long> redisScript = new DefaultRedisScript(script, Long.class); | ||
141 | + Long result = redisTemplate.execute(redisScript, Lists.newArrayList(key), value); | ||
142 | + if (RELEASE_OK.equals(result)) { | ||
143 | + log.info("release lock ok, key is {} value is {}", key, value); | ||
144 | + return true; | ||
145 | + } else { | ||
146 | + log.info("release lock ko, key is {} value is {}", key, value); | ||
147 | + return false; | ||
148 | + } | ||
149 | + } | ||
150 | + | ||
151 | + private boolean releaseOr(String value, boolean defaultValue) { | ||
152 | + try { | ||
153 | + return release(value); | ||
154 | + } catch (Exception e) { | ||
155 | + // try once | ||
156 | + try { | ||
157 | + return release(value); | ||
158 | + } catch (Exception e2) { | ||
159 | + log.info("release lock ko, key is {} value is {}", key, value, e2); | ||
160 | + return defaultValue; | ||
161 | + } | ||
162 | + } | ||
163 | + } | ||
164 | + | ||
165 | + private void updateLockValue() { | ||
166 | + lockValue = UUID.randomUUID().toString(); | ||
167 | + } | ||
168 | + | ||
169 | + /** | ||
170 | + * 线程等待时间 | ||
171 | + * | ||
172 | + * @param millis 毫秒 | ||
173 | + * @param nanos 纳秒 | ||
174 | + */ | ||
175 | + private void sleep(long millis, int nanos) { | ||
176 | + try { | ||
177 | + Thread.sleep(millis, random.nextInt(nanos)); | ||
178 | + } catch (InterruptedException e) { | ||
179 | + log.info("lock {} sleep interrupted ", key, e); | ||
180 | + } | ||
181 | + } | ||
182 | + | ||
183 | + | ||
184 | +} |
1 | +package com.yohoufo.common.lock; | ||
2 | + | ||
3 | +import org.springframework.data.redis.core.RedisTemplate; | ||
4 | + | ||
5 | +import java.util.concurrent.TimeUnit; | ||
6 | + | ||
7 | + | ||
8 | +public interface RedisLock { | ||
9 | + | ||
10 | + /** | ||
11 | + * 阻塞方式的获取锁 | ||
12 | + * | ||
13 | + * @return 是否成功获得锁 | ||
14 | + */ | ||
15 | + boolean lock(); | ||
16 | + | ||
17 | + /** | ||
18 | + * 获取锁 超时返回 | ||
19 | + * | ||
20 | + * @return | ||
21 | + */ | ||
22 | + boolean lock(long timeout, TimeUnit timeUnit); | ||
23 | + | ||
24 | + /** | ||
25 | + * 尝试获取锁 立即返回 | ||
26 | + * | ||
27 | + * @return 是否成功获得锁 | ||
28 | + */ | ||
29 | + boolean tryLock(); | ||
30 | + | ||
31 | + /** | ||
32 | + * 解锁 | ||
33 | + */ | ||
34 | + boolean unlock(); | ||
35 | + | ||
36 | + static Builder builder() { | ||
37 | + return new Builder(); | ||
38 | + } | ||
39 | + | ||
40 | + static RedisLock create(RedisTemplate redisTemplate, String key, long expireTime, TimeUnit timeUnit) { | ||
41 | + return builder() | ||
42 | + .redisTemplate(redisTemplate) | ||
43 | + .key(key) | ||
44 | + .expireTime(expireTime, timeUnit) | ||
45 | + .build(); | ||
46 | + } | ||
47 | + | ||
48 | + | ||
49 | + class Builder { | ||
50 | + | ||
51 | + RedisTemplate redisTemplate; | ||
52 | + | ||
53 | + String key; | ||
54 | + | ||
55 | + long expireTimeMillis; | ||
56 | + | ||
57 | + private Builder() { | ||
58 | + | ||
59 | + } | ||
60 | + | ||
61 | + public Builder redisTemplate(RedisTemplate redisTemplate) { | ||
62 | + this.redisTemplate = redisTemplate; | ||
63 | + return this; | ||
64 | + } | ||
65 | + | ||
66 | + public Builder key(String key) { | ||
67 | + this.key = key; | ||
68 | + return this; | ||
69 | + } | ||
70 | + | ||
71 | + public Builder expireTime(long expireTime, TimeUnit timeUnit) { | ||
72 | + this.expireTimeMillis = timeUnit.toMillis(expireTime); | ||
73 | + return this; | ||
74 | + } | ||
75 | + | ||
76 | + public RedisLock build() { | ||
77 | + return new DefaultRedisLock(this); | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | +} | ||
82 | + |
1 | +package com.yohoufo.common.lock; | ||
2 | + | ||
3 | +import com.yoho.core.redis.cluster.annotation.Redis; | ||
4 | +import com.yoho.core.redis.cluster.operations.nosync.YHRedisTemplate; | ||
5 | +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; | ||
6 | +import lombok.extern.slf4j.Slf4j; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | + | ||
9 | +import java.util.concurrent.TimeUnit; | ||
10 | + | ||
11 | +@Service | ||
12 | +@Slf4j | ||
13 | +public class RedisLockFactory { | ||
14 | + | ||
15 | + @Redis("gwNoSyncRedis") | ||
16 | + private YHRedisTemplate redis; | ||
17 | + | ||
18 | + public RedisLock newLock(RedisKeyBuilder keyBuilder, final long timeout, final TimeUnit unit) { | ||
19 | + return RedisLock.create(redis.getStringRedisTemplate(), keyBuilder.getKey(), timeout, unit); | ||
20 | + } | ||
21 | + | ||
22 | +} |
@@ -5,11 +5,9 @@ import com.yohoufo.common.ApiResponse; | @@ -5,11 +5,9 @@ import com.yohoufo.common.ApiResponse; | ||
5 | import com.yohoufo.common.annotation.IgnoreSession; | 5 | import com.yohoufo.common.annotation.IgnoreSession; |
6 | import com.yohoufo.common.annotation.IgnoreSignature; | 6 | import com.yohoufo.common.annotation.IgnoreSignature; |
7 | import com.yohoufo.common.annotation.InnerApi; | 7 | import com.yohoufo.common.annotation.InnerApi; |
8 | -import com.yohoufo.common.cache.RedisLock; | ||
9 | -import com.yohoufo.common.exception.UfoServiceException; | 8 | +import com.yohoufo.common.lock.RedisLock; |
9 | +import com.yohoufo.common.lock.RedisLockFactory; | ||
10 | import com.yohoufo.common.utils.ExecutorServiceUtils; | 10 | import com.yohoufo.common.utils.ExecutorServiceUtils; |
11 | -import com.yohoufo.common.utils.RandomUtil; | ||
12 | -import com.yohoufo.order.model.QuickDeliverOrderContext; | ||
13 | import com.yohoufo.order.model.request.TransferMoneyRequest; | 11 | import com.yohoufo.order.model.request.TransferMoneyRequest; |
14 | import com.yohoufo.order.service.impl.TransferService; | 12 | import com.yohoufo.order.service.impl.TransferService; |
15 | import com.yohoufo.order.utils.NamedThreadFactory; | 13 | import com.yohoufo.order.utils.NamedThreadFactory; |
@@ -36,7 +34,7 @@ public class OrderHelpController { | @@ -36,7 +34,7 @@ public class OrderHelpController { | ||
36 | private TransferService transferService; | 34 | private TransferService transferService; |
37 | 35 | ||
38 | @Autowired | 36 | @Autowired |
39 | - private RedisLock redisLock; | 37 | + private RedisLockFactory redisLockFactory; |
40 | 38 | ||
41 | /** | 39 | /** |
42 | * 转账 | 40 | * 转账 |
@@ -64,7 +62,7 @@ public class OrderHelpController { | @@ -64,7 +62,7 @@ public class OrderHelpController { | ||
64 | 60, TimeUnit.SECONDS, | 62 | 60, TimeUnit.SECONDS, |
65 | new ArrayBlockingQueue<>(1000), NamedThreadFactory.newThreadFactory("test")); | 63 | new ArrayBlockingQueue<>(1000), NamedThreadFactory.newThreadFactory("test")); |
66 | 64 | ||
67 | - IntStream.range(0, 10) | 65 | + IntStream.range(0, 100) |
68 | .forEach(i -> executorService.submit(() -> lockTest(key))); | 66 | .forEach(i -> executorService.submit(() -> lockTest(key))); |
69 | ExecutorServiceUtils.shutdownAndAwaitTermination(executorService); | 67 | ExecutorServiceUtils.shutdownAndAwaitTermination(executorService); |
70 | return new ApiResponse.ApiResponseBuilder() | 68 | return new ApiResponse.ApiResponseBuilder() |
@@ -77,18 +75,18 @@ public class OrderHelpController { | @@ -77,18 +75,18 @@ public class OrderHelpController { | ||
77 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() | 75 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() |
78 | .appendFixed("ufo:order:lock:test:") | 76 | .appendFixed("ufo:order:lock:test:") |
79 | .appendVar(key); | 77 | .appendVar(key); |
80 | - String value = UUID.randomUUID().toString(); | ||
81 | - if (redisLock.acquire(redisLockKey, value, 5, TimeUnit.SECONDS)) { | 78 | + RedisLock lock = redisLockFactory.newLock(redisLockKey,5, TimeUnit.SECONDS); |
79 | + if (lock.tryLock()) { | ||
82 | try { | 80 | try { |
83 | - log.info("lock test {}, {} i got the lock", key, value); | ||
84 | - Thread.sleep(RandomUtils.nextInt(4000, 5000)); | 81 | + log.info("lock test {}, i got the lock", key); |
82 | + Thread.sleep(RandomUtils.nextInt(10, 50)); | ||
85 | } catch (InterruptedException e) { | 83 | } catch (InterruptedException e) { |
86 | 84 | ||
87 | } finally { | 85 | } finally { |
88 | - redisLock.release(redisLockKey, value); | 86 | + lock.unlock(); |
89 | } | 87 | } |
90 | } else { | 88 | } else { |
91 | - log.info("lock test {}, {} i not got the lock", key, value); | 89 | + log.info("lock test {}, i not got the lock", key); |
92 | } | 90 | } |
93 | } | 91 | } |
94 | 92 |
@@ -16,9 +16,9 @@ import com.yohobuy.ufo.model.order.resp.PageResp; | @@ -16,9 +16,9 @@ import com.yohobuy.ufo.model.order.resp.PageResp; | ||
16 | import com.yohobuy.ufo.model.order.resp.SellerGoodsPageResp; | 16 | import com.yohobuy.ufo.model.order.resp.SellerGoodsPageResp; |
17 | import com.yohoufo.common.alarm.EventBusPublisher; | 17 | import com.yohoufo.common.alarm.EventBusPublisher; |
18 | import com.yohoufo.common.alarm.SmsAlarmEvent; | 18 | import com.yohoufo.common.alarm.SmsAlarmEvent; |
19 | -import com.yohoufo.common.cache.RedisLock; | 19 | +import com.yohoufo.common.lock.RedisLock; |
20 | +import com.yohoufo.common.lock.RedisLockFactory; | ||
20 | import com.yohoufo.common.exception.UfoServiceException; | 21 | import com.yohoufo.common.exception.UfoServiceException; |
21 | -import com.yohoufo.common.utils.StringUtil; | ||
22 | import com.yohoufo.dal.order.SellerOrderGoodsViewMapper; | 22 | import com.yohoufo.dal.order.SellerOrderGoodsViewMapper; |
23 | import com.yohoufo.dal.order.model.SellerOrderGoods; | 23 | import com.yohoufo.dal.order.model.SellerOrderGoods; |
24 | import com.yohoufo.order.model.QuickDeliverOrderContext; | 24 | import com.yohoufo.order.model.QuickDeliverOrderContext; |
@@ -34,8 +34,6 @@ import com.yohoufo.order.service.seller.orderMeta.SellerOrderMetaService; | @@ -34,8 +34,6 @@ import com.yohoufo.order.service.seller.orderMeta.SellerOrderMetaService; | ||
34 | import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator; | 34 | import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator; |
35 | import com.yohoufo.order.utils.LoggerUtils; | 35 | import com.yohoufo.order.utils.LoggerUtils; |
36 | import org.apache.commons.collections.CollectionUtils; | 36 | import org.apache.commons.collections.CollectionUtils; |
37 | -import org.apache.commons.lang3.RandomUtils; | ||
38 | -import org.apache.commons.lang3.StringUtils; | ||
39 | import org.slf4j.Logger; | 37 | import org.slf4j.Logger; |
40 | import org.springframework.beans.factory.annotation.Autowired; | 38 | import org.springframework.beans.factory.annotation.Autowired; |
41 | import org.springframework.stereotype.Service; | 39 | import org.springframework.stereotype.Service; |
@@ -85,19 +83,19 @@ public class QuickDeliverGoodsService { | @@ -85,19 +83,19 @@ public class QuickDeliverGoodsService { | ||
85 | private SellerNoticeFacade sellerNoticeFacade; | 83 | private SellerNoticeFacade sellerNoticeFacade; |
86 | 84 | ||
87 | @Autowired | 85 | @Autowired |
88 | - private RedisLock redisLock; | 86 | + private RedisLockFactory redisLockFactory; |
89 | 87 | ||
90 | public DepositPublishResp publish(QuickDeliverOrderSubmitReq req) { | 88 | public DepositPublishResp publish(QuickDeliverOrderSubmitReq req) { |
91 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() | 89 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() |
92 | .appendFixed("ufo:order:lock:publishQuickDeliverGoods:") | 90 | .appendFixed("ufo:order:lock:publishQuickDeliverGoods:") |
93 | .appendVar(req.getUid() + "-" + req.getStorageId()); | 91 | .appendVar(req.getUid() + "-" + req.getStorageId()); |
94 | - String value = UUID.randomUUID().toString(); | ||
95 | - if (redisLock.acquire(redisLockKey, value,5, TimeUnit.SECONDS)) { | 92 | + RedisLock lock = redisLockFactory.newLock(redisLockKey,5,TimeUnit.SECONDS); |
93 | + if (lock.tryLock()) { | ||
96 | try { | 94 | try { |
97 | QuickDeliverOrderContext qdoc = quickDeliverPublishProcessor.buildPublishCtx(req); | 95 | QuickDeliverOrderContext qdoc = quickDeliverPublishProcessor.buildPublishCtx(req); |
98 | return doPublish(qdoc); | 96 | return doPublish(qdoc); |
99 | } finally { | 97 | } finally { |
100 | - redisLock.release(redisLockKey,value); | 98 | + lock.unlock(); |
101 | } | 99 | } |
102 | } else { | 100 | } else { |
103 | logger.warn("storage has publishing , {} ", redisLockKey); | 101 | logger.warn("storage has publishing , {} ", redisLockKey); |
@@ -4,9 +4,9 @@ import com.alibaba.fastjson.JSONObject; | @@ -4,9 +4,9 @@ import com.alibaba.fastjson.JSONObject; | ||
4 | import com.google.common.collect.Lists; | 4 | import com.google.common.collect.Lists; |
5 | import com.google.common.collect.Sets; | 5 | import com.google.common.collect.Sets; |
6 | import com.yoho.core.config.ConfigReader; | 6 | import com.yoho.core.config.ConfigReader; |
7 | -import com.yoho.core.redis.cluster.annotation.Redis; | ||
8 | -import com.yoho.core.redis.cluster.operations.nosync.YHValueOperations; | ||
9 | import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; | 7 | import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; |
8 | +import com.yohoufo.common.lock.RedisLock; | ||
9 | +import com.yohoufo.common.lock.RedisLockFactory; | ||
10 | import com.yohoufo.common.utils.DateUtil; | 10 | import com.yohoufo.common.utils.DateUtil; |
11 | import com.yohoufo.dal.order.BuyerOrderGoodsMapper; | 11 | import com.yohoufo.dal.order.BuyerOrderGoodsMapper; |
12 | import com.yohoufo.dal.order.SellerOrderMetaMapper; | 12 | import com.yohoufo.dal.order.SellerOrderMetaMapper; |
@@ -59,8 +59,8 @@ public class HkAccountSettlement { | @@ -59,8 +59,8 @@ public class HkAccountSettlement { | ||
59 | @Autowired | 59 | @Autowired |
60 | private SellerOrderMetaMapper sellerOrderMetaMapper; | 60 | private SellerOrderMetaMapper sellerOrderMetaMapper; |
61 | 61 | ||
62 | - @Redis("gwNoSyncRedis") | ||
63 | - private YHValueOperations valueOperations; | 62 | + @Autowired |
63 | + private RedisLockFactory redisLockFactory; | ||
64 | 64 | ||
65 | 65 | ||
66 | public void settle(Integer uid) { | 66 | public void settle(Integer uid) { |
@@ -69,12 +69,11 @@ public class HkAccountSettlement { | @@ -69,12 +69,11 @@ public class HkAccountSettlement { | ||
69 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() | 69 | RedisKeyBuilder redisLockKey = RedisKeyBuilder.newInstance() |
70 | .appendFixed("ufo:order:hkAccount:settle:") | 70 | .appendFixed("ufo:order:hkAccount:settle:") |
71 | .appendVar(uid + "-" + dealTime); | 71 | .appendVar(uid + "-" + dealTime); |
72 | - String redisLockValue = "Y"; | ||
73 | - if (redisLockValue.equals(valueOperations.get(redisLockKey))) { | 72 | + RedisLock redisLock = redisLockFactory.newLock(redisLockKey,5, TimeUnit.SECONDS); |
73 | + if (!redisLock.tryLock()) { | ||
74 | log.info("{} settle fail, it already in the process", uid); | 74 | log.info("{} settle fail, it already in the process", uid); |
75 | return; | 75 | return; |
76 | } | 76 | } |
77 | - valueOperations.set(redisLockKey, redisLockValue, 5, TimeUnit.SECONDS); | ||
78 | // 没有要打款的账单 | 77 | // 没有要打款的账单 |
79 | if (!tryLock(uid, dealTime)) { | 78 | if (!tryLock(uid, dealTime)) { |
80 | log.info("{} settle fail, it already in the process", uid); | 79 | log.info("{} settle fail, it already in the process", uid); |
@@ -113,6 +112,7 @@ public class HkAccountSettlement { | @@ -113,6 +112,7 @@ public class HkAccountSettlement { | ||
113 | log.info("{} settle, sun income is {} but limit {}", uid, sumIncome, limitAmount); | 112 | log.info("{} settle, sun income is {} but limit {}", uid, sumIncome, limitAmount); |
114 | releaseLockWithRetry(uid, dealTime); | 113 | releaseLockWithRetry(uid, dealTime); |
115 | } | 114 | } |
115 | + redisLock.unlock(); | ||
116 | } | 116 | } |
117 | 117 | ||
118 | private List<TradeBillResult> getTradeBillResults(Integer uid, List<TradeBills> tradeBills) { | 118 | private List<TradeBillResult> getTradeBillResults(Integer uid, List<TradeBills> tradeBills) { |
-
Please register or login to post a comment