[英]java methods and race condition in a jsp/servlets application
假设我有一个名为doSomething()
的方法,我想在多线程应用程序中使用此方法(每个servlet都继承自HttpServlet)。我想知道在下列情况下是否可能出现竞争条件:
doSomething()
不是staic方法 ,它将值写入数据库。 doSomething()
是静态方法,但它不会将值写入数据库。 我注意到我的应用程序中的许多方法可能会导致竞争条件或脏读/写。 例如,我有一个轮询系统,并且对于每个投票操作,某个方法将更改该轮询的单个单元格值,如下所示:
[poll_id | poll_data ]
[1 | {choice_1 : 10, choice_2 : 20}]
JSP / Servlets应用程序会自己解决这些问题,还是我必须自己解决所有问题?
谢谢..
这取决于doSomething()
的实现方式和实际操作方式。 我假设写入数据库使用的JDBC连接不是线程安全的。 这样做的首选方法是创建ThreadLocal
JDBC连接。
至于第二种情况,它取决于方法中发生了什么。 如果它不访问任何共享的,可变的状态,那么就没有问题。 如果是这样,您可能需要适当地锁定,这可能涉及向每个其他访问这些变量的锁添加锁。
(请注意,仅将这些方法标记为已synchronized
不会修复任何并发错误。如果doSomething()
在共享对象上增加一个值,则需要synchronized
对该变量的所有访问,因为i++
不是原子操作。如果是像递增计数器这样简单的东西,你可以使用AtomicInteger.incrementAndGet()
。)
Servlet API当然不会神奇地使并发成为非问题。
写入数据库时,它取决于持久层中的并发策略。 悲观锁定,乐观锁定,最后胜利? 当你“写入数据库”时,你需要决定如何处理,还有更多的事情要做。 当两个人同时点击按钮时你想要发生什么?
使doSomething静态似乎对这个问题没有多大影响。 正在发生的事情是相关部分。 它是修改静态变量吗? 然后是的,可能会有竞争条件。
servlet api不会为你做任何事情让你的并发问题消失。 在servlet上使用synchronized关键字这样的事情是个坏主意,因为你基本上强迫你的线程一次处理一个,这会破坏你对多个用户快速响应的能力。
如果使用Spring或EJB3,则任何一个都将提供线程本地数据库连接以及指定事务的能力。 你一定要看看其中一个。
情况1,您的servlet使用一些访问数据库的代码。 数据库具有您应该利用的锁定机制。 这有两个重要原因:数据库本身可能会从其他读取和写入数据的应用程序中使用,但这还不足以让您的应用程序处理与自身竞争的问题。 而且:您自己的应用程序可能会部署到一个扩展的集群Web容器中,其中您的代码的多个副本在不同的计算机上执行。
因此,有许多标准模式可以处理数据库中的锁,您可能需要阅读悲观和乐观锁定。
servlet API和JBC连接池为您提供了一些有用的保证,这样您就可以在不使用Java同步的情况下编写servlet代码,前提是您的变量在方法范围内,在概念上您有
Start transaction (perhaps implicit, perhaps on entry to an ejb)
Get connection to DB ( Gets you a connection from pool, associated with your tran)
read/write/update code
Close connection (actually keeps it for your thread until your transaction commits)
Commit (again maybe implictly)
因此,您唯一真正的问题是处理数据库中的任何争用。 以上所有这些都倾向于使用诸如JPA之类的东西更好地完成,但是在或多或少的情况下正在发生的事情。
案例2:静态方法,这可能意味着您现在将所有内容都保存在内存结构中。 这(禁止某种远程调用)会影响单个JVM并管理您自己的锁定。 如果您的JVM或机器崩溃,我猜您会丢失数据。 如果您关心数据,那么使用数据库可能会更好。
或者,如何完全采用其他方法:servlet通过将消息写入持久性JMS队列来简单地记录“投票”。 让一些其他进程从队列中获取投票并添加它们。 您不会以这种方式立即向选民提供反馈,但您将用户的体验与实际(在类似场景中)相当复杂的处理分离。
我认为你的问题的最佳解决方案是使用“synchronized”关键字和wait / notify之类的东西!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.