1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| package org.pt;
import jakarta.annotation.Resource; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.scripting.support.ResourceScriptSource; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.UUID; import java.util.concurrent.TimeUnit;
@Service(value = "DistributedLockService") public class DistributedLockService {
private static final String LOCK_KEY_PREFIX = "lock:";
@Resource private StringRedisTemplate stringRedisTemplate;
private static final DefaultRedisScript<Long> LOCK_SCRIPT; private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
static { LOCK_SCRIPT = new DefaultRedisScript<>(); LOCK_SCRIPT.setScriptSource(new ResourceScriptSource(new ClassPathResource("scripts/lock.lua"))); LOCK_SCRIPT.setResultType(Long.class);
UNLOCK_SCRIPT = new DefaultRedisScript<>(); UNLOCK_SCRIPT.setScriptSource(new ResourceScriptSource(new ClassPathResource("scripts/unlock.lua"))); UNLOCK_SCRIPT.setResultType(Long.class); }
public boolean tryLock(String resourceName, String lockValue, long expireTime, TimeUnit unit) { String key = LOCK_KEY_PREFIX + resourceName; long expireMillis = unit.toMillis(expireTime); Long result = stringRedisTemplate.execute( LOCK_SCRIPT, Collections.singletonList(key), lockValue, String.valueOf(expireMillis) );
return result != null && result == 1L; }
public void unlock(String resourceName, String lockValue) { String key = LOCK_KEY_PREFIX + resourceName; stringRedisTemplate.execute(UNLOCK_SCRIPT, Collections.singletonList(key), lockValue); }
public void processOrder(String orderId) { String lockValue = UUID.randomUUID().toString(); if (tryLock("order:" + orderId, lockValue, 30, TimeUnit.SECONDS)) { try { System.out.println("成功获取锁,开始处理订单:" + orderId); Thread.sleep(500); System.out.println("订单处理完成:" + orderId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { unlock("order:" + orderId, lockValue); System.out.println("释放锁:" + orderId); } } else { System.out.println("获取锁失败,请稍后重试:" + orderId); } } }
|