为什么需要分布式系统锁
比如系统中的注册
需要先判断用户账号是否被注册 没有被注册则保存用户注册信息数据
在单系统情况下 可以这样做
String username = user.getUsername();
synchronized (username.intern()) {//防止多用户情况下 输入的相同账号都还未保存成功的情况下越过检查
if(userService.existUsername(username,"")){
mav.addObject("usernameMessage","用户名已存在");
return mav;
}
userService.save(user);
}
集群情况下可能是不同的服务器处理 无法阻止
分布式事务锁 底层借助memcached实现
/**
* 业务锁
*
* 通过 memcache 的 addCache获取锁
*
* @author 820381
*
*/
public class Lock {
/**
* 锁
* @param lockName
* @return true 成功/false 失败
*/
public static boolean lock(String lockName) {
return getLock(lockName, 0);
}
/**
* 解除锁
* @param lockName
* @return
*/
public static boolean unlock(String lockName) {
return CacheUtil.deleteKeyCache(lockName);
}
/**
* 锁,并在获得锁的时候执行回调,回调执行完成后,解除锁
* @param lockName 锁名
* @param call 回调函数
* @return BusinessRuntimeException: ExceptionCode.CMN_LOCK_FAILED
* @throws BusinessException
*/
public static <T> T lock(String lockName, Callback<T> call) throws BusinessException {
if(lock(lockName)) {
try {
return call.handle();
} finally {
unlock(lockName);
}
} else {
throw new BusinessException(ExceptionCode.CMN_LOCK_FAILED,
MessageFormat.format("连接超时[{0}]", lockName));
}
}
private static boolean getLock(String lockName, Integer count) {
boolean gotLock = false;
if(count > 1000) {
return gotLock;
}
while(true) {
gotLock = CacheUtil.addCache(lockName, true, null);
if(gotLock) {
return gotLock;
} else {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// 不处理异常睡眠异常
}
return getLock(lockName, ++count);
}
}
}
}
/**
*
* @ClassName: CacheUtil
* @Description: 缓存工具类
* @author Fanhy
* @date 2014-11-27 上午10:55:39
*
*/
public class CacheUtil {
/**
* 缓存客户端
*/
private static MemCachedClient memCachedClient;
/**
* 过期时间
*/
private String timeLenght;
/**
* 默认Key的超时时间(小于1000的值,除以1000以后都是0,即永不过期 )
*/
private static Date keyTimeOut;
@SuppressWarnings("unused")
private void init() {
keyTimeOut = new Date(Integer.parseInt(timeLenght));// 24小时缓存
}
/**
*
* @MethodName: getKeyCache
* @Description: 获取缓存
* @param keyName
* 缓存键
* @return 返回数据
*/
public static Object getKeyCache(String keyName) {
if (null != keyName) {
MemcachedItem item = memCachedClient.gets(keyName);
if (null != item) {
return item.getValue();
}
}
return null;
}
/**
*
* @MethodName: setCache
* @Description: 设置缓存
* @param keyName
* 缓存主键
* @param value
* 缓存数据
* @param date
* 过期时间(new Date(60000)过期时间是60秒)(如不设置默认缓存24小时)(不得超过30天)
*/
public static void setCache(String keyName, Object value, Date date) {
if (null != keyName && !"".equals(keyName)) {
if (null == date) {
memCachedClient.set(keyName, value, keyTimeOut);
} else {
memCachedClient.set(keyName, value, date);
}
}
}
/**
*
* @MethodName: setCache
* @Description: 设置缓存
* @param keyName
* 缓存主键
* @param value
* 缓存数据
*/
public static void setCache(String keyName, Object value) {
if (null != keyName && !"".equals(keyName)) {
memCachedClient.set(keyName, value, keyTimeOut);
}
}
/**
*
* @MethodName: deleteKeyCache
* @Description: 删除缓存
* @param keyName
* key名称
*/
public static boolean deleteKeyCache(String keyName) {
if (null != keyName && !"".equals(keyName)) {
return memCachedClient.delete(keyName);
}
return false;
}
public void setMemCachedClient(MemCachedClient memCachedClient) {
CacheUtil.memCachedClient = memCachedClient;
}
public void setTimeLenght(String timeLenght) {
this.timeLenght = timeLenght;
}
/**
*
* @MethodName: addCache
* @Description: 设置缓存不重复Key,暂时只用于分布式同步
* @param keyName
* @param value
* @param date
* @return void 返回类型
*/
public static boolean addCache(String keyName, Object value, Date date) {
boolean isTrue = false;
if (!StringUtils.isBlank(keyName)) {
if (null == date) {
Date dt = new Date();
date = DateUtils.addMinutes(dt, 3);
}
isTrue = memCachedClient.add(keyName, value, date);
}
return isTrue;
}
}
如何使用
@Aspect
@Component
public class LockAspect {
@Around("execution(* com.sfiec..*.*(..)) && @annotation(Lock)")
public Object around(final ProceedingJoinPoint point) throws Throwable {
String lockName = getLockName(point);
return com.sfiec.oms.common.Lock.lock(lockName, new Callback<Object>() {
@Override
public Object handle() throws BusinessException {
Object result;
try {
result = point.proceed();
} catch (Throwable e) {
if(e instanceof BusinessException) {
throw (BusinessException) e;
}
if(e instanceof BusinessRuntimeException) {
throw (BusinessRuntimeException) e;
}
throw new BusinessException("", e);
}
return result;
}
});
}
private String getLockName(ProceedingJoinPoint point) {
MethodSignature signature = MethodSignature.class.cast(point.getSignature());
Lock lock = signature.getMethod().getAnnotation(Lock.class);
// 不是自定义的锁标志的退出
if(lock == null) {
return null;
}
// 获取默认的锁
String lockName = lock.value();
// 不存在占位符,则直接返回
if(lockName.indexOf("${") == -1) {
return lockName;
}
// 获取占位符的内容
final Properties properties = new Properties();
String[] parameterNames = signature.getParameterNames();
Object[] args = point.getArgs();
for(int i = 0; i < parameterNames.length; i++) {
String name = parameterNames[i];
Object val = args[i];
if(isBaseDataType(val.getClass())) {
val = String.valueOf(val);
}
properties.put(name, val);
}
// TODO 如果存在 ${xx.xx} 属性,则使用反射获取内容
// 一般的 ${xxx},直接获取内容
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
String lockName2 = helper.replacePlaceholders(lockName, properties);
return lockName2;
}
/**
* 判断一个类是否为基本数据类型。
* @param clazz 要判断的类。
* @return true 表示为基本数据类型。
*/
@SuppressWarnings("rawtypes")
private static boolean isBaseDataType(Class clazz) {
return
(
clazz.equals(String.class) ||
clazz.equals(Integer.class)||
clazz.equals(Byte.class) ||
clazz.equals(Long.class) ||
clazz.equals(Double.class) ||
clazz.equals(Float.class) ||
clazz.equals(Character.class) ||
clazz.equals(Short.class) ||
clazz.equals(BigDecimal.class) ||
clazz.equals(BigInteger.class) ||
clazz.equals(Boolean.class) ||
clazz.equals(Date.class) ||
clazz.isPrimitive()
);
}
}
@Lock(CommonConstant.LOCK_REGISTER + " ${user.username}")
public boolean register(User user) {
if(userService.existUsername(username,"")){
mav.addObject("usernameMessage","用户名已存在");
return false;
}
userService.save(user);
return true;
}
相关推荐
本文讨论了分布式锁的实现方案,主要基于Redis实现分布式锁,以解决分布式系统中资源访问的同步问题。在分布式系统中,需要协调各个系统或主机之间的资源访问,以避免彼此干扰和保证一致性。分布式锁是控制分布式...
Redisson是基于Redis的Java客户端,它提供了丰富的数据结构和服务,包括分布式锁、信号量、队列、计数器等,极大地扩展了Redis在分布式系统中的应用能力。本篇文章将详细探讨如何使用Redisson实现Redis分布式事务锁...
"利用分布式共享锁实现防止方法重复调用"这一主题,主要涉及到如何通过分布式锁来解决这类问题。本文将深入探讨分布式锁的概念、其在防刷单场景中的应用以及如何利用Redis实现分布式锁。 分布式锁是一种在分布式...
在IT行业中,尤其是在大型分布式系统的设计与开发中,分布式锁是一种关键的同步机制。本篇文章将深入探讨如何在C#.NET环境下利用Redis实现分布式锁,以及相关的核心知识点。 首先,让我们理解什么是分布式锁。...
分布式锁是一种在分布式系统中实现同步的技术,它允许多个节点在同一时刻访问共享资源。在大型分布式环境中,由于网络延迟和并发操作,简单的本地锁可能无法有效解决数据一致性问题。这时,Zookeeper,一个高可用的...
Curator提供了现成的分布式锁实现,如`InterProcessMutex`和`InterProcessSemaphoreMutex`,并且提供了易用的API,使得开发人员可以更简单地使用Zookeeper进行分布式锁的实现。 在上述代码片段中,`LockUtil`类是...
Redis分布式锁实现Redisson 15问 Redis分布式锁是指在分布式系统中,多个服务实例之间对同一个资源...Redisson是一个功能强大且高效的分布式锁实现,它提供了一个可靠的加锁机制,可以满足分布式系统中的加锁需求。
分布式锁是一种在分布式系统中解决资源竞争问题的重要机制。在单机环境中,我们可以通过Java等编程语言内置的并发控制手段,如synchronized关键字或ReentrantLock等实现锁。然而,在分布式环境中,由于多台服务器...
在分布式系统中,为了保证数据的一致性和安全性,分布式锁是一种常见的解决方案。Redis作为一个高性能的键值存储系统,常被用作实现分布式锁的工具。本文将深入探讨如何使用Redis实现分布式锁,以及如何利用自旋式...
zk分布式锁1 在分布式系统中,分布式锁是必...ZooKeeper分布式锁是一种高效、灵活的分布式锁实现方案,广泛应用于分布式系统中。但是,需要根据不同的分布式系统需求进行选择和配置,以确保分布式锁的正确性和高效性。
**Zookeeper的分布式锁实现原理** 1. **节点创建与监视**: Zookeeper允许客户端创建临时节点,这些节点会在客户端断开连接时自动删除。分布式锁的实现通常会为每个请求创建一个临时顺序节点,按照创建的顺序形成一...
在分布式系统中,由于网络延迟、服务器故障等问题,一致性与协调是常见的挑战。Zookeeper,一个由Apache Hadoop项目开发的分布式协调服务,为解决这些问题提供了强大的支持。它被广泛用于实现分布式锁、配置管理、...
《大规模分布式系统架构与设计实战》写到,分布式并行计算的基本原理解剖;分布式协调的实现,包括如何实现公共配置管理,如何实现分布式锁,如何实现集群管理等;分布式缓存的实现,包括如何提供完整的分布式缓存来...
在分布式系统中,为了保证数据的一致性和安全性,分布式锁是一种常见的解决方案。本文将深入探讨如何使用Redisson和Curator框架来实现Java环境中的分布式锁。 首先,让我们来看一下Redisson实现的分布式锁。Redis是...
在IT行业中,尤其是在高并发的电子商务系统中,"redis分布式锁实现抢单秒杀"是一个常见的挑战。这个场景模拟了多个用户同时参与秒杀活动,系统需要确保库存的准确性和抢单的公平性,避免超卖和数据不一致的问题。...
分布式锁是一种在分布式系统中实现同步访问资源的关键技术。它允许多个节点在同一时间对共享资源进行互斥访问,确保在高并发环境下数据的一致性和完整性。在这个“分布式锁简单实现”项目中,开发者提供了一个基本的...
4. **负载均衡**:为了提高系统性能,分布式系统需要实现负载均衡,将工作负载合理分配到各个节点。这涉及策略如轮询、权重分配、哈希分布等。 5. **容错与恢复**:分布式系统必须具备处理硬件故障、网络问题和软件...
分布式系统设计是现代互联网服务和企业级应用的核心技术之一,它涉及到多个计算机节点通过网络进行协同工作,共同处理任务和数据。在这个领域,我们需要深入理解并掌握一系列关键知识点,以构建高效、可扩展且容错的...
分布式锁是一种常见的分布式系统协调机制,用于控制分布式环境下的多个进程或线程之间的访问顺序,防止多个客户端同时修改共享资源,从而保证数据的一致性和完整性。分布式锁通常有三种实现方式:基于关系数据库的...
在分布式系统中,锁是保证数据一致性的重要工具,而Redisson的分布式锁则为Java开发者提供了一种高效且可靠的解决方案。 首先,让我们深入理解分布式锁的概念。分布式锁是在分布式系统中,为了确保多个节点对共享...