Spring会话-异步调用处理

Spring会话-异步调用处理,spring,spring-session,spring-data-redis,gemfire,spring-data-gemfire,Spring,Spring Session,Spring Data Redis,Gemfire,Spring Data Gemfire,Spring会话管理负责异步调用吗 假设我们有多个控制器,每个控制器都在读取/写入不同的会话属性。当会话对象完全写入/读取到外部服务器,而不仅仅是属性时,是否会出现并发问题 我们面临这样一个问题,即控制器设置的属性在下一次读取时不存在。。。这是一个间歇性问题,取决于其他控制器的并行执行 当我们使用容器中的会话对象时,我们从未遇到过这个问题。。。假设它是一个直接属性集/直接发生在内存中的会话对象上。会话的一般用例是存储一些特定于用户的数据。如果我正确理解了您的上下文,那么您的问题描述了这样一种场景

Spring会话管理负责异步调用吗

假设我们有多个控制器,每个控制器都在读取/写入不同的会话属性。当会话对象完全写入/读取到外部服务器,而不仅仅是属性时,是否会出现并发问题

我们面临这样一个问题,即控制器设置的属性在下一次读取时不存在。。。这是一个间歇性问题,取决于其他控制器的并行执行


当我们使用容器中的会话对象时,我们从未遇到过这个问题。。。假设它是一个直接属性集/直接发生在内存中的会话对象上。

会话的一般用例是存储一些特定于用户的数据。如果我正确理解了您的上下文,那么您的问题描述了这样一种场景:一个用户,例如从两个设备(例如PC和电话)进行身份验证,因此不受同一会话的限制正在以如此之快的速度访问后端请求,以至于您在读取和写入会话数据时面临并发问题

对于会话来说,这不是一个常见的(也是合理的)场景,因此像
spring-data-redis
spring-data-gemfire
这样的项目不支持开箱即用


好消息是spring会话的构建考虑到了灵活性,因此您当然可以实现您想要的。您可以实现自己版本的
SessionRepository
,并手动同步(例如通过Redis分布式锁)相关方法。但是,在执行此操作之前,请检查您的设计,并确保您使用的会话用于正确的数据存储作业

会话的一般用例是存储一些特定于用户的数据。如果我正确理解了您的上下文,那么您的问题描述了这样一种场景:一个用户,例如从两个设备(例如PC和电话)进行身份验证,因此不受同一会话的限制正在以如此之快的速度访问后端请求,以至于您在读取和写入会话数据时面临并发问题

对于会话来说,这不是一个常见的(也是合理的)场景,因此像
spring-data-redis
spring-data-gemfire
这样的项目不支持开箱即用


好消息是spring会话的构建考虑到了灵活性,因此您当然可以实现您想要的。您可以实现自己版本的
SessionRepository
,并手动同步(例如通过Redis分布式锁)相关方法。但是,在执行此操作之前,请检查您的设计,并确保您使用的会话用于正确的数据存储作业

这个问题在本质上与您的问题非常相似。在阅读我的回答/评论之前,你应该先阅读这个问题

匿名用户先前发布的答案(和见解)相当准确

只要您有一个高度并发(Web)的应用程序/环境,其中有许多不同的、同时的HTTP请求进入,访问同一个HTTP会话,那么总是有可能由于竞争并发HTTP请求之间的竞争条件而导致更新丢失。这是由于Servlet容器(例如ApacheTomcat或EclipseJetty)的本质造成的,因为每个HTTP请求都是由一个单独的线程处理的

Servlet容器提供的HTTP会话对象不仅需要是线程安全的,Web应用程序放入HTTP会话的所有应用程序域对象也需要是线程安全的。因此,请注意这一点

此外,大多数HTTP会话实现,如Apache Tomcat,甚至是由不同会话管理提供程序(如Spring会话数据Redis或Spring会话数据GemFire)支持的Spring会话实现,都广泛使用“Delta”来只向会话状态发送更改(或差异),通过最大限度地减少由于竞争条件而丢失更新的机会,实现了这一目标

例如,如果HTTP会话当前的属性键/值为
1/A
,HTTP请求1(由线程1处理)读取HTTP会话(仅
1/A
)并添加属性
2/B
,而另一个并发HTTP请求2(由线程2处理)根据会话ID读取相同的HTTP会话(看到与
1/A
相同的初始会话状态),现在希望添加
3/C
,然后作为Web应用程序开发人员,我们希望在线程1和2中的请求1和2完成后,最终结果和HTTP会话状态将包括属性:
[1/A,2/B,3/C]

但是,如果两个(甚至更多)竞争的HTTP请求都在修改,比如HTTP sessoin attribute
1/A
,HTTP请求/线程1希望将该属性设置为
1/B
,而竞争的HTTP请求/线程2希望将同一属性设置为
1/C
,那么谁获胜

事实证明,最后1个线程获胜,或者更确切地说,最后一个写入HTTP会话状态的线程获胜,结果可能是
1/B
1/C
,这是不确定的,受调度、网络延迟、负载等变幻莫测因素的影响。事实上,几乎不可能推断会发生哪种情况,更不用说alwa了这种情况经常发生

虽然我们的匿名用户提供了一些上下文,比如说,一个用户同时使用多个设备(一个网络浏览器,也许还有一个移动设备……智能手机或平板电脑),但用一个用户再现这种错误,即使是多个用户也不是不可能的,但可能性非常小

但是,如果我们在生产环境中考虑这一点,比如说,您可能有数百个Web应用程序实例,分布在多台物理机器、VM或容器等上,由一些网络负载均衡器/设备进行负载平衡,并且