java – 如何获得对某些会话条目的独占访问权限?

前端之家收集整理的这篇文章主要介绍了java – 如何获得对某些会话条目的独占访问权限?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
由于REST服务的远程调用特性,它们处于不断变为竞争条件的状态.比赛的日常资源之一是会议.为了切实可行,您需要能够在流程开始时锁定资源,并在完成任务后将其解除.

现在我的问题是,Spring Session是否有任何功能来处理会话条目中的竞争条件?

或者Java中的任何其他库/框架!

解决方法

如果您使用的是Spring Controllers,那么您可以使用

RequestMappingHandlerAdapter.setSynchronizeOnSession-boolean-

这将使每个Controller方法在会话存在时同步.

HttpSession.setAttribute是线程安全的.但是getAttribute后跟setAttribute必须手动安全.

synchronized(session) {
    session.setAttribute("foo","bar");
    session.getAttribute("foo");
}

在spring会话bean的情况下可以做同样的事情.

synchronized(session) {
    //do something with the session bean
}

#编辑

如果多个容器具有普通的spring会话bean,则必须使用粘性会话.这将确保一个会话状态存储在一个容器中,并且每次请求相同会话时都访问该容器.这必须在BigIP cookie之类的帮助下在负载均衡器上完成.休息将与单个会话存在单个容器的方式相同,因此锁定会话就足够了.

如果您希望跨实例使用会话共享,则对容器(例如TomcatJetty)提供支持

这些方法使用后端数据库或其他一些持久性机制来存储状态.

出于同样的目的,您可以尝试使用Spring Session.使用Redis进行配置非常简单.由于Redis是单线程的,因此可确保以原子方式访问条目的一个实例.

以上方法是非侵入性的.数据库和基于Redis的方法支持transactions.

但是,如果您想要更好地控制分布式状态和锁定,可以尝试使用分布式数据网格,如Hazelcast和Gemfire.

我亲自与Hazelcast合作,它确实提供了methods to lock entries made in the map.

#EDIT2

虽然我认为处理事务应该足以满足Spring Session和Redis,以确保您需要分布式锁定.必须从Redis本身获取锁定对象.由于Redis是单线程的,因此个人实现也可以使用像INCR这样的东西

算法将如下所示

//lock_num is the semaphore/lock object

lock_count = INCR lock_num
while(true) {
    if(lock_count != 1) {
        DECR lock_num
    } else {
        break
    }
    wait(wait_time_period)
}

//do processing in critical section

DECR lock_num

但是,幸运的是,Spring已经通过RedisLockRegistry提供了这种分布式锁实现.更多文档于usage is here.

如果您决定使用没有弹簧的普通Jedis,那么这里是Jedis的分布式锁:Jedis Lock.

//from https://github.com/abelaska/jedis-lock
Jedis jedis = new Jedis("localhost");
JedisLock lock = new JedisLock(jedis,"lockname",10000,30000);
lock.acquire();
try {
  // do some stuff
}
finally {
  lock.release();
}

这两个都应该像Hazelcast锁定一样工作.

猜你在找的Java相关文章