[英]Java EE: Why do we need to know about Concurrency?
我从著名的书– Mastering Enterprise JavaBeans™3.0中摘录以下几行。
并发访问和锁定:始终通过事务隔离保护对数据库中数据的并发访问,因此,如果适当使用事务,则无需设计其他并发控件来保护应用程序中的数据。 除非您做出特定规定,否则将使用为持久性提供程序和/或EJB容器的事务服务配置的隔离级别,通过容器管理的事务来保护您的实体。 但是,了解并发控制要求和应用程序的语义很重要。
然后讨论Java事务API,容器管理的和Bean管理的事务,不同的TransactionAttributes,不同的隔离级别。 它还指出-
Java Persistence规范定义了两个可以针对同时访问的实体进行调整的重要功能:1.使用版本属性的乐观锁定2.明确的读写锁定
好的-我阅读了所有内容并很好地理解了它们。 但是问题来了,在哪种情况下我需要使用所有这些技术? 如果我使用容器托管事务,并且为我做所有事情,为什么我需要麻烦所有这些细节? 我知道TransactionAttributes的重要性(REQUIRED,REQUIRES_NEW),并且知道在哪些情况下需要使用它们,其他情况又如何呢? 进一步来说 -
对于Q2和Q3-我认为Entity类不是线程安全的,因此我们需要在那儿锁定。 但是数据库是由JTA API在EJB类中管理的(如第一段所述),那么为什么我们需要分别管理Entity类呢? 我知道锁定和版本的工作方式以及为什么需要它们。 但是,由于JTA已经存在,为什么它们会出现在图中?
您能给他们答案吗? 如果您给我提供一些URL,那将是非常感谢。
提前谢谢了。
您不需要锁定,因为实体类不是线程安全的。 实体不能在线程之间共享,仅此而已。
您的数据库带有ACID保证,但这并不总是足够的,有时您需要显式地锁定行以获取所需的内容。 想象以下情况:
最终结果是工资为4000。启动事务A的用户完全不知道,即使他将工资设置为3000,另一个用户同时将其设置为4000。根据最后写入的事务,最终结果为不同(因此不可预测)。 使用乐观锁定可以避免这种情况。
下一种情况:您希望生成纯顺序的发票编号,而不会丢失值且不会重复。 您可以想象读取并递增数据库中的值来执行此操作。 但是,两个事务可能都同时读取相同的值,然后将其递增。 因此,您将有一个副本。 在持有下一个数字的表行中使用锁可以避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.