如何在Java EE应用程序中锁定数据库记录?

时间:2012-10-01 15:37:02

标签: java java-ee jpa transactions

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

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

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

  • 使用JPA;

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

  • 有一个MyObject类,其属性idname存储在MYOBJECT表格中;

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

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

    < / LI>

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

(另一个细节:Here描述了EntityTransaction和UserTransaction之间的区别。如果我理解正确,只有在我使用多个数据库时才需要JTA。如果我只使用一个不同的Oracle数据库,它也是必要的吗schemas?如果是,请使用JTA编写示例代码。)

2 个答案:

答案 0 :(得分:11)

1)如果要锁定数据库中的记录,则需要一个名为悲观锁的内容。请记住此关键字并将其用于进一步的Google搜索。简单地说,悲观锁意味着真正锁定数据库中的记录。这意味着如果您的Java应用程序产生悲观锁定,则记录真正锁定;所以即使其他一些非Java程序访问同一个数据库,该记录也会被锁定,并且无法对其进行修改。

另一方面,所谓的乐观锁主要是假装锁。大概是“我们最有可能无论如何都不需要锁定此记录,所以我们不会真正锁定它,而如果发生了不好的事情,那么我们将尝试以解决问题后“接近。这实际上是有意义的并且提高了性能,但仅限于这种方法背后的假设是正确的情况;冲突真的很罕见,以及你真正可以解决问题的地方。除非你理解得很好(你似乎没有),否则就不要使用它。

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

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

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

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

答案 1 :(得分:-9)

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

提示:使用@Version

请阅读此处了解有关locking for JPA

的信息