Java 集群并发处理方法

简讯ing 发布于 2016/05/10 12:56
阅读 2K+
收藏 1
业务需求
1.一个业务流程会涉及到多个表联动操作
2.在业务流程中其中一个表操作出现问题该次业务流程操作会全部回滚。
3.这个业务流程中有多个表都需要取原数据进行计算


目前的使用场景
1.一台机器一个jvm 通过synchronized对操作方法进行加锁
2.对service进行事物回滚,如果出现异常就回滚


需解决的业务场景
随着业务需求现在做了服务器集群有两台机器,这个时候就有两个jvm了因此synchronized已无法满足,用什么办法可以解决这个多个jvm的线程并发问题


自己的理解
1.因为设计到多表的联合操作因此不太适合通过DB来阻止这个问题




注:如果可以用DB剞劂这个问题,能否详细告知解决方法,或者其他的解决方法。。谢谢
加载中
1
拐子
拐子

没法理解楼主的使用场景,举个例子说哈

比如有个Account类 id=10000001,money=200 需求是同时在手机APP和PC网页上申请提现200元,不考虑使用数据库的特性来防止余额变成-200
原来单JVM操作的时候只需要 synchronized Account对象就OK了
synchronized(account){
if(account.money >= 200){
account.money -= 200;
Thread.sleep(1000);//模拟业务操作时间
}else{
//余额不足 提现失败
}
......
}


到了多JVM环境下 APP和PC的请求很有可能被分发到不同的JVM下,这时synchronized显然无法保证结果的准确性
此时的关键是保证同一时刻,只有1个JVM对id=10000001的account对象进行余额变动的操作
boolean lock = false;
try{
lock = DistributedLock.tryLock("account",10000001,超时时间);
//得到锁
if(lock){
if(account.money >= 200){
account.money -= 200;
Thread.sleep(1000);//模拟业务操作时间
}else{
//余额不足 提现失败
}
}else{
//获取不到锁
}
}catch(Execption e){
//异常处理
}finally{
if (lock) {
//释放锁
DistributedLock.unLock("account", 10000001);
}


}


0
拐子
拐子

用redis或memcached做分布式锁吧

简讯ing
简讯ing
zookeeper其实也可以用于分布式锁吧?在查资料当中获得的
0
简讯ing
简讯ing

引用来自“拐子”的评论

用redis或memcached做分布式锁吧

查了下相关的信息redis 和memcached相当于是借助第三方的一个软件,通过网络来判断执行方式是么?刚才扫了一眼没弄明白好像是用于缓存的。。那么分布式锁的应用 该如何处理呢?。。我是spring 的。
yues
yues
楼主的这种情况,如果将这类业务做成存储过程,然后加事物,直接. 也可以用redis,memcache这种公共缓存,做请求标记,
0
xpbob
xpbob
两个JVM的话,是否考虑用网络通讯或者进程通讯的方式,考虑用传递信号来让逻辑串行
0
简讯ing
简讯ing

引用来自“拐子”的评论

没法理解楼主的使用场景,举个例子说哈

比如有个Account类 id=10000001,money=200 需求是同时在手机APP和PC网页上申请提现200元,不考虑使用数据库的特性来防止余额变成-200
原来单JVM操作的时候只需要 synchronized Account对象就OK了
synchronized(account){
if(account.money >= 200){
account.money -= 200;
Thread.sleep(1000);//模拟业务操作时间
}else{
//余额不足 提现失败
}
......
}


到了多JVM环境下 APP和PC的请求很有可能被分发到不同的JVM下,这时synchronized显然无法保证结果的准确性
此时的关键是保证同一时刻,只有1个JVM对id=10000001的account对象进行余额变动的操作
boolean lock = false;
try{
lock = DistributedLock.tryLock("account",10000001,超时时间);
//得到锁
if(lock){
if(account.money >= 200){
account.money -= 200;
Thread.sleep(1000);//模拟业务操作时间
}else{
//余额不足 提现失败
}
}else{
//获取不到锁
}
}catch(Execption e){
//异常处理
}finally{
if (lock) {
//释放锁
DistributedLock.unLock("account", 10000001);
}


}


已经明白了。。谢谢兄弟
0
海淀游民
海淀游民
你的业务需求其实就是电商的秒杀问题,用队列,效率最高,也最好控制
海淀游民
海淀游民
回复 @简讯ing : http://www.oschina.net/question/12_57749?fromerr=EJBXrDYT
简讯ing
简讯ing
队列针对集群也有效么?
0
0
ihuotui
ihuotui

分布式事务啊。简单自己控制,覆盖大就使用xa。

0
简讯ing
简讯ing
最终找到一个解决方法是通过阿里云的队列功能完成这个分布式锁的功能
返回顶部
顶部