繁体   English   中英

Java EE:为什么我们需要了解并发性?

[英]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),并且知道在哪些情况下需要使用它们,其他情况又如何呢? 进一步来说 -

  1. 为什么需要Bean托管交易?
  2. 为什么我们需要对实体类进行读写锁定?
  3. 为什么需要版本属性?

对于Q2和Q3-我认为Entity类不是线程安全的,因此我们需要在那儿锁定。 但是数据库是由JTA API在EJB类中管理的(如第一段所述),那么为什么我们需要分别管理Entity类呢? 我知道锁定和版本的工作方式以及为什么需要它们。 但是,由于JTA已经存在,为什么它们会出现在图中?

您能给他们答案吗? 如果您给我提供一些URL,那将是非常感谢。

提前谢谢了。

您不需要锁定,因为实体类不是线程安全的。 实体不能在线程之间共享,仅此而已。

您的数据库带有ACID保证,但这并不总是足够的,有时您需要显式地锁定行以获取所需的内容。 想象以下情况:

  • 事务A从数据库中读取员工1
  • 事务B从数据库读取员工1
  • 交易A将员工1的工资设置为3000
  • 事务B将员工1的工资设置为4000
  • 事务A提交
  • 事务B提交

最终结果是工资为4000。启动事务A的用户完全不知道,即使他将工资设置为3000,另一个用户同时将其设置为4000。根据最后写入的事务,最终结果为不同(因此不可预测)。 使用乐观锁定可以避免这种情况。

下一种情况:您希望生成纯顺序的发票编号,而不会丢失值且不会重复。 您可以想象读取并递增数据库中的值来执行此操作。 但是,两个事务可能都同时读取相同的值,然后将其递增。 因此,您将有一个副本。 在持有下一个数字的表行中使用锁可以避免这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM