1

我想编写一个 Java EE Web 应用程序,其中不同的用户使用数据库。用户可以开始编辑记录,然后保存更改或取消编辑。当用户正在编辑时,应该为其他用户锁定记录。它应该被锁定在数据库级别,因为还有其他非 Java 用户正在编辑同一个数据库,锁定他们处理的记录。

我了解一些基本的 Java + 数据库,但我不擅长锁定等多用户操作。在 Internet 上寻找一些示例,在我看来,Java EE 技术的每个“hello world”示例都至少介绍了另一种技术。为了访问数据库中的对象,我使用 JPA。要锁定记录,我可能需要事务,这带来了 JTA。要使用 JTA,我需要 JNDI。要使用所有这些对象,我可能还需要 EJB 和注入......此时我想知道这是否真的是解决问题的最简单方法,或者我是否错过了一些重要的东西。我不知道是否所有这些技术都是必要的(如果是,我使用它们; 我只是想在我全部学习之前确定)。我只是看到我在网上找到的例子非常慷慨地介绍它们。

我想要一个简单的 Java EE 代码示例:

  • 使用 JPA;

  • 连接到“persistence.xml”文件中描述的数据库;

  • 有一个MyObject具有属性id和的类name,存储在MYOBJECT表中;

  • 有一个方法(例如,从 JSP 页面调用),该方法在数据库级别锁定对象id = 42(因此有权访问同一数据库的非 Java 用户也无法修改它),或者如果记录已被另一个锁定,则显示错误用户(另一个 Java 用户或非 Java 用户);

  • 有另一个方法(例如,从另一个 JSP 调用),它要么将 更新name为指定值并释放锁,要么在提供空字符串时释放锁。

对于您在解决方案中引入的每项新技术,我想听听您为什么使用它的简短解释。此外,该技术是否需要我安装新库、创建或修改配置文件、编写附加代码等。(调用方法的 JSP 文件不是必需的;我对与数据库相关的部分感兴趣。)

(另一个细节:这里描述了EntityTransaction和UserTransaction之间的区别。如果我理解正确的话,只有当我使用多个数据库时才需要JTA。如果我只使用一个具有不同模式的Oracle数据库,是否也需要?如果是,请使用 JTA 编写示例代码。)

4

2 回答 2

12

1)如果你想锁定数据库中的记录,你需要一种叫做悲观锁的东西。记住此关键字并将其用于进一步的谷歌搜索。简单地说,悲观锁意味着真正锁定数据库中的记录。这意味着如果您的 Java 应用程序进行了悲观锁定,则记录确实被锁定;所以即使其他一些非Java程序访问同一个数据库,记录也会被锁定,他们不能修改它。

另一方面,所谓的乐观锁多是假装锁。这大概是一种“我们很可能无论如何都不需要锁定这条记录,所以我们不会真正锁定它,如果发生了不好的事情,那么我们会在之后尝试解决问题”的方法。这实际上是有意义的并提高了性能,但仅在这种方法背后的假设为真的情况下;那里的冲突真的很少见,而且你以后真的可以解决问题。除非您很好地理解它(您似乎不理解),否则不要使用它。

2) JPA 是一种使用具有事务和东西的数据库的统一方法,它还为您将对象映射到表。这可能就是你想要的。

JTA 是相同的东西,加上在许多数据库上使用事务的统一方法,因此它比 JPA 更强大,但这意味着它具有并不真正需要的附加功能。另一方面,为了使用这些超级大国,你需要付出一些代价,比如失去启动和随心所欲的交易的能力。服务器将根据服务器的需要为您管理事务。如果您完全了解它的工作原理,那么您就知道这是否符合您的需求;但如果你不这样做,那么你宁愿避免它。您的开发环境可能会为您提供 JTA 作为默认选项,但这只是因为它认为您要编写 Skynet。通过不使用 JTA,您也不必使用 JNDI、EJB 和许多其他与天网相关的技术。

3) 听完之后,现在是你做功课的时候了。因为现在你知道该做什么了。阅读“javax.persistence”API 文档。

您可以使用带注释的 Java 类来表示您的数据库表;或者你可以使用老式的 SQL 查询;或两者兼而有之,如您所愿。您可以使用它们中的任何一个来锁定和释放记录。锁必须在事务内部,因此如果要保留锁,则必须保留事务。

于 2013-01-09T14:23:08.987 回答
-11

我们不会为您解决这个问题。你要求一切。您需要自己编写代码,但这里是 JPA 锁定的链接。

提示:使用@Version

阅读此处了解有关JPA 锁定的信息

于 2012-10-01T16:14:00.720 回答