【问题标题】:Java EE: Why do we need to know about Concurrency?Java EE:为什么我们需要了解并发?
【发布时间】:2014-09-20 14:08:22
【问题描述】:

我从著名的书 - Mastering Enterprise JavaBeans™ 3.0 中提取以下几行。

并发访问和锁定:对数据库中数据的并发访问始终受到事务隔离的保护,因此您无需设计额外的并发控制来保护您的 如果事务使用得当,应用程序中的数据。除非您做出具体规定,否则您的实体将受到容器管理事务的保护,这些事务使用为持久性提供程序和/或 EJB 容器的事务服务配置的隔离级别。但是,了解应用程序的并发控制要求和语义很重要。

然后谈到Java Transaction API、Container Managed 和Bean Managed Transaction、不同的TransactionAttributes、不同的隔离级别。它还指出 -

Java Persistence 规范定义了两个重要的特性 针对同时访问的实体进行了调整: 1.使用版本属性的乐观锁 2.显式读写锁

好的 - 我阅读了所有内容并很好地理解了它们。但问题是在哪种情况下我需要使用所有这些技术?如果我使用 Container Managed transaction 并且它为我做了所有事情,为什么我需要关心所有这些细节?我知道 TransactionAttributes (REQUIRED, REQUIRES_NEW) 的重要性并且知道在哪些情况下我需要使用它们,但是其他的呢?更具体地说-

  1. 为什么需要 Bean 托管事务?
  2. 为什么我们需要实体类的读写锁?
  3. 为什么我们需要版本属性?

对于第二季度和第三季度——我认为实体类不是线程安全的,因此我们需要在那里锁定。但是数据库是由 JTA API 在 EJB 类中管理的(如第一段所述),那么为什么我们需要单独管理 Entity 类呢?我知道 Lock 和 Version 如何工作以及为什么需要它们。但是既然 JTA 已经存在,为什么他们会出现呢?

你能回答他们吗?如果您给我一些网址,我们将不胜感激。

非常感谢。

【问题讨论】:

  • 深思 -> 您将如何设计一个可以在应用程序级别维护 ACID 属性的事务管理系统?例如:文件系统的事务管理系统
  • 感谢 Satadru 的思考。我将阅读更多书籍以澄清我的疑问。再次感谢。

标签: java multithreading hibernate concurrency transactions


【解决方案1】:

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

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

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

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

下一个场景:您想要生成纯粹的连续发票编号,没有丢失值和重复。你可以想象在数据库中读取和增加一个值来做到这一点。但是两个事务可能同时读取相同的值,然后递增它。因此,您将有一个副本。在持有下一个数字的表行中使用锁可以避免这种情况。

【讨论】:

  • 感谢各位宝贵的 cmets 和贡献。我过去两周不在,因此无法早点回复。再次感谢我。
猜你喜欢
  • 2016-02-14
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2017-02-26
相关资源
最近更新 更多