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之类的帮助下在负载均衡器上完成.休息将与单个会话存在单个容器的方式相同,因此锁定会话就足够了. 如果您希望跨实例使用会话共享,则对容器(例如Tomcat和Jetty)提供支持 这些方法使用后端数据库或其他一些持久性机制来存储状态. 出于同样的目的,您可以尝试使用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锁定一样工作. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
