【发布时间】:2014-09-06 02:30:05
【问题描述】:
我在 Tomcat 中运行 Java Web 服务。
该服务由多个 Rails 应用程序使用,这些应用程序应该协调并发修改,但做得不是很好。
只有一种感兴趣的服务方法会尝试 PUT 用户记录,但它会进行大量处理并且可能需要一段时间。很有可能不止一个 Rails 应用程序会尝试将更改推送给同一用户,而之前的调用仍在处理中。
我对 Tomcat 的每个请求一个线程的理解是,我实际上是在处理多线程问题,但我不想在服务对象上同步,而是想以某种方式在瞬态用户 ID 上同步。
我想到了使用 Set 来存储当前处理的用户 ID,然后在集合的对象上进行同步。能够将用户 ID 添加到集合中的第一个可以进行处理,而发现集合中已有用户 ID 的则返回,例如 409 冲突错误。
Set<String> activeUserIds = new HashSet<String>();
// annotations, mappings, etc.
public ResponseEntity<String> putUser(User user) {
boolean canProcess;
synchoronize(activeUserIds) {
canProcess = activeUserIds.add(user.getId()) {
}
if (!canProcess) {
return new ResponseEntity<String>("user already being modified", Status.CONFLICT);
}
// perform service activity
synchoronize(activeUserIds) {
activeUserIds.remove(user.getId()) {
}
}
这听起来可行吗?我还没有发现 Tomcat 或 Spring MVC 中内置的任何东西可以自动处理这种行为,但是是否已经有我不知道的内置解决方案?
【问题讨论】:
-
任何使用 Java 并发操作的解决方案(仅)只能在您的应用程序未跨多台机器/JVM 集群时工作。您使用什么后端存储来存储用户记录?如果您使用的是 SQL 数据库,则可以在请求处理代码的开头锁定该行。
标签: java multithreading spring tomcat