现在互联网下,分布式,微服务横行,难免会遇到分布式下的事务问题,但是很多场景是需要分布式事务的,下面我就来介绍下java和.net下一种常用的分布式事务的解决方案
java 版
1、redisson 这里不做介绍,网上有很多,本文主要要讲怎么使用
<!--redis分布式锁-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.4.3</version>
</dependency>
生成Redisson的bean
支持单机,主从,哨兵,集群等模式
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient getRedisson() {
Config config = new Config();
config.useClusterServers()
.setScanInterval(1000) // 集群状态扫描间隔时间,单位是毫秒
//可以用"rediss://"来启用SSL连接
.addNodeAddress("redis://192.168.1.22:6729")
.addNodeAddress("redis://192.168.1.23:6729")
.addNodeAddress("redis://192.168.1.24:6729")
.addNodeAddress("redis://192.168.1.25:6729")
.addNodeAddress("redis://192.168.1.26:6729");
return (Redisson)Redisson.create(config);
}
}
这里只演示集群环境。
这里只是简单展示,详细配置网上有很多,在这里就不做详细说明了
package com.yl.soft.yb.common.redis; import org.redisson.api.*; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; /** * redisson操作类 */ @Service("redissonService") public class RedissonService { @Autowired private RedissonClient redissonClient; public void getRedissonClient() throws IOException { Config config = redissonClient.getConfig(); System.out.println(config.toJSON().toString()); } /** * ` * 获取字符串对象 * * @param objectName * @return */ public <T> RBucket<T> getRBucket(String objectName) { RBucket<T> bucket = redissonClient.getBucket(objectName); return bucket; } /** * 获取Map对象 * * @param objectName * @return */ public <K, V> RMap<K, V> getRMap(String objectName) { RMap<K, V> map = redissonClient.getMap(objectName); return map; } /** * 获取有序集合 * * @param objectName * @return */ public <V> RSortedSet<V> getRSortedSet(String objectName) { RSortedSet<V> sortedSet = redissonClient.getSortedSet(objectName); return sortedSet; } /** * 获取集合 * * @param objectName * @return */ public <V> RSet<V> getRSet(String objectName) { RSet<V> rSet = redissonClient.getSet(objectName); return rSet; } /** * 获取列表 * * @param objectName * @return */ public <V> RList<V> getRList(String objectName) { RList<V> rList = redissonClient.getList(objectName); return rList; } /** * 获取队列 * * @param objectName * @return */ public <V> RQueue<V> getRQueue(String objectName) { RQueue<V> rQueue = redissonClient.getQueue(objectName); return rQueue; } /** * 获取双端队列 * * @param objectName * @return */ public <V> RDeque<V> getRDeque(String objectName) { RDeque<V> rDeque = redissonClient.getDeque(objectName); return rDeque; } /** * 获取锁 * * @param objectName * @return */ public RLock getRLock(String objectName) { RLock rLock = redissonClient.getLock(objectName); return rLock; } /** * 获取读取锁 * * @param objectName * @return */ public RReadWriteLock getRWLock(String objectName) { RReadWriteLock rwlock = redissonClient.getReadWriteLock(objectName); return rwlock; } /** * 获取原子数 * * @param objectName * @return */ public RAtomicLong getRAtomicLong(String objectName) { RAtomicLong rAtomicLong = redissonClient.getAtomicLong(objectName); return rAtomicLong; } /** * 获取记数锁 * * @param objectName * @return */ public RCountDownLatch getRCountDownLatch(String objectName) { RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(objectName); return rCountDownLatch; } /** * 获取消息的Topic * * @param objectName * @return */ public RTopic getRTopic(String objectName) { RTopic rTopic = redissonClient.getTopic(objectName); return rTopic; } }
简单使用实现:
@Autowired
RedissonService redissonService;
public String addOrder(String orderparams){
RLock lock = redisson.getLock(key);
RLock lock = redissonService.getRLock("declare_" + token);
try {
boolean bs = lock.tryLock(5, 6, TimeUnit.SECONDS);
if (bs) {
//处理业务代码
return "获取锁成功!";
} else {
return "获取锁失败";
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (lock.isLocked())
lock.unlock();
} catch (Exception ex) {
}
}
.net 版
有很多种 本文只介绍一种 采用ServiceStack.Redis实现Redis分布式锁
/*
* Redis分布式锁
* 采用ServiceStack.Redis实现的Redis分布式锁
* 详情可阅读其开源代码
* 备注:不同版本的 ServiceStack.Redis 实现reidslock机制不同 xxf里面默认使用2.2版本
*/ public class RedisDistributedLock : BaseRedisDistributedLock
{
private ServiceStack.Redis.RedisLock _lock;
private RedisClient _client;
public RedisDistributedLock(string redisserver, string key)
: base(redisserver, key)
{
}
public override LockResult TryGetDistributedLock(TimeSpan? getlockTimeOut, TimeSpan? taskrunTimeOut)
{
if (lockresult == LockResult.Success)
throw new DistributedLockException("检测到当前锁已获取");
_client = DistributedLockConfig.GetRedisPoolClient(redisserver).GetClient();
/* * 阅读源码发现当其获取锁后,redis连接资源会一直占用,知道获取锁的资源释放后,连接才会跳出,可能会导致连接池资源的浪费。 */
try {
this._lock = new ServiceStack.Redis.RedisLock(_client, key, getlockTimeOut);
lockresult = LockResult.Success;
}
catch (Exception exp)
{
XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁系统级别严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp);
lockresult = LockResult.LockSystemExceptionFailure;
}
return lockresult;
}
public override void Dispose()
{
try {
if (this._lock != null)
this._lock.Dispose();
if (_client != null)
this._client.Dispose();
}
catch (Exception exp)
{
XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁释放严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp);
}
}
}