我正在开发一个Java Web应用程序,它涉及为每个用户分配某些资源。
服务器在用户登录时将资源分配给用户,并在用户注销/会话超时时回收。
有多个服务器实例在运行Web,同时无法在它们之间共享相同的资源。因此,一旦将资源分配给用户,它就是该用户独有的,直到服务器回收或停止运行。因此,服务器端必须能够检查资源的可用性并在压缩时释放它(否则无法通过其他服务器实例重新分配资源)。
我的计划是将资源定义存储在数据库表中,每条记录代表一个这样的资源,并在资源分配给用户后让每个服务器从中读取并锁定记录,这样就不会有其他服务器实例可以在使用时再次分配它,服务器故障会释放锁并使资源可用。
问题是此记录级别锁定必须无限期保持活动,即只要用户保持在线,锁定就会通知其他服务器已经分配了资源。
所以我想知道是否可以在JDBC或hibernate中应用这种锁?如果不可能,是否有任何替代方案可以在没有锁定的情况下达到相同的效果?
答案 0 :(得分:0)
不,数据库锁不适用于此类用法。锁是交易的一部分,交易应该很短。
您可以使用额外的表"资源使用"来管理资源的状态。它可以有一个与资源定义ID相关的列,一个"正在使用"标志,用户标识,服务器标识和上次使用资源的时间。
服务器可以通过插入或更新“资源使用”中的行来为用户声明资源。表和设置"在使用" flag为true(这需要在一个简短的事务中完成)。如果两个服务器/事务声明相同的资源,则一个事务将失败(或更新将导致更新0行)。抓住这个失败并重复另一个无人认领的资源的行动。
当服务器启动时,它需要检查任何声明的资源并取消它们(例如,如果服务器被杀死并再次启动)。如果服务器崩溃,则另一台服务器必须取消崩溃服务器声明的资源。这意味着服务器以某种方式了解彼此的健康状况(在线/离线)。一种方法是使用"资源服务器和#34;其中每个服务器定期更新特定于服务器的行中的时间戳:如果时间戳没有更新一段时间,则另一个健康的服务器可以决定从已脱机的服务器中取消资源。请注意:要做到这一点很棘手(例如,如果数据库离线一段时间,服务器必须等待一段时间后数据库再次重新联机,然后再查找脱机服务器)。也许你可以找到一个替代资源服务器"表格使用某种聚类技术来解决这个问题。
最后,每个服务器内的清扫服务需要观看"最后使用的" "正在使用的时间戳"资源。清扫服务应该没有任何报告,但如果会话丢失或清理代码没有正常运行,清扫服务将至少通知您资源泄漏。