在java中锁定一个特定的方法

时间:2013-09-13 10:37:04

标签: java ajax concurrency

在我的java webappication中,有一个动作可以更新订单对象并通过ajax调用(POST请求)将其保存在DB中。

方法saveOrder()执行此操作, 如果多个用户执行相同的操作,则应该锁定此方法,以便使用最新数据执行写入事务。

类文件代码如下

public class OrderLoader extends JSONProcessSimple {

@override
public JSONObject exec(JSONObject jsonsent) throws JSONException, ServletException {
  JSONObject result = this.saveOrder(array);
  return result;
}

public JSONObject saveOrder(JSONArray jsonarray) throws JSONException {
        JSONObject jsonResponse = new JSONObject();
        //Write operation on DB
        return jsonResponse;
    }
}

是否可以通过同步方法,请建议我一个解决方案。

提前致谢!

4 个答案:

答案 0 :(得分:2)

根据应用程序的体系结构(它是否在集群环境中的多个并行实例中运行?),没有简单的解决方案;如果它只在一个VM中执行,synchronized可能是一种方法。另外,请查看java.util.concurrent.lock包。

对于更复杂的分布式方法,您可以实现基于数据库的锁定。

答案 1 :(得分:2)

更好的解决方案是检查数据库isolation和SQL。也许您需要SERIALZIABLE连接或事务管理器。那是服务器端。

添加synchronized关键字很容易,但我认为不仅如此。

http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html

http://www.precisejava.com/javaperf/j2ee/JDBC.htm

答案 2 :(得分:1)

同步所有人都不会完成这项工作,因为你要阻止,直到第一个请求被保存,然后你仍然需要检查其他订单是否更新。

正如其他人已经说过的那样,没有简单的解决方案,这取决于你的架构和环境。

您可能希望尝试某种优化锁定方法,即每次更新都会检查版本列,并在版本匹配时将其递增。像... SET version = x + 1 WHERE version = x之类的东西,然后检查列是否已更新。

这不会获得最新的订单保存,但会防止丢失更新。但是,您可以调整该方法,只有在有新数据时才更新数据库(可能基于某个日期,然后使用WHERE date > x)。

编辑

由于你正在使用Hibernate,我会研究Hibernate的乐观锁定。这至少会处理并发编辑,因为只有第一个会成功。如果非并发编辑导致OptimisticLockExceptions,您可能在某处错过了(重新)读取。

使用并发编辑我的意思是用户A读取对象,更改它然后触发写入。在用户B之间也读取了对象并稍后触发写入。写入不是并发的,但用户B没有看到用户A的更改,因此可能导致更新丢失。

在您的情况下,它将取决于对订单执行的操作。在某些情况下,您可以在保持更改之前安全地重新读取订单(例如,在添加位置时,删除它们时甚至可以这样做 - 如果位置不存在则您什么都不做)而在其他情况下您可能会这样做想要报告并发编辑(例如,当两个用户编辑相同位置的数量,订单标题等时)。

答案 3 :(得分:0)

如果您的方法更新了不同用户的订单,那么您不需要进行任何同步,因为每个访问该方法的线程都有自己的副本,因此不需要考虑。

但是如果所有用户都在使用相同的数据,则可以在begintransaction和endtransaction中使用write to db。这应该使并发写线程安全。