Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我需要什么Hibernate锁定模式来读取和更新对象,同时阻止其他人这样做?_Java_Hibernate_Concurrency_Locking - Fatal编程技术网

Java 我需要什么Hibernate锁定模式来读取和更新对象,同时阻止其他人这样做?

Java 我需要什么Hibernate锁定模式来读取和更新对象,同时阻止其他人这样做?,java,hibernate,concurrency,locking,Java,Hibernate,Concurrency,Locking,在以下代码示例中: Session session = getSessionFactory().openSession(); MyObject currentState = (MyObject) session.get(MyObject.class, id, new LockOptions(LockMode.???)); if (!statusToUpdateTo.equals(currentState.getStatus())) { tx

在以下代码示例中:

   Session session = getSessionFactory().openSession();

   MyObject currentState = (MyObject) 
           session.get(MyObject.class, id, new LockOptions(LockMode.???));

   if (!statusToUpdateTo.equals(currentState.getStatus())) {
     tx = session.beginTransaction();

     currentState.setStatus(statusToUpdateTo);
     session.save(currentState);

     tx.commit();
   }

   session.close();
正如您可能希望从代码中解释的那样,其想法是检查我们的存储并找到具有给定id的对象,然后将其更新为给定状态。如果我们发现对象已经处于我们想要更新的状态,我们就放弃做任何事情。否则,我们将更新状态并将其保存回存储

我担心的是,如果这些请求中的几个同时通过,并且所有请求都试图读取和更新同一个对象,该怎么办?通过doco查看,Hibernate似乎通常会自动获得正确的锁级别。类,但我仍然希望确保只有一种东西可以读取对象,决定需要更新它,然后再更新它—而没有任何其他线程对同一数据库条目执行相同的操作


从LockMode类中,我认为悲观主义是我所追求的,但似乎找不到证实这一点的文档资源。有人能帮我确认这一点,并且上面的代码将完成我要做的事情吗?

因此,我在原始代码中注意到,在会话关闭时,数据库上仍然保留着一个锁,因为在调用tx.commit时,删除我插入的行的后续调用没有完成

在添加下面的else块之后,我的测试通过了,我推断这意味着锁已经被释放,因为这些行正在被清理

   Session session = getSessionFactory().openSession();

   MyObject currentState = (MyObject) 
           session.get(MyObject.class, id, 
                       new LockOptions(LockMode.PESSIMISTIC_WRITE));

   if (!statusToUpdateTo.equals(currentState.getStatus())) {
     tx = session.beginTransaction();

     currentState.setStatus(statusToUpdateTo);
     session.save(currentState);

     tx.commit();
   } else {
     // Seems to clear lock
     tx = session.beginTransaction();
     tx.rollback();
   }

   session.close();
对我来说,这显然反映了我对Hibernate的锁定机制缺乏了解,但使用session获得锁似乎有点奇怪。。。或会话。加载。。。然后不使用会话本身释放锁,而是仅通过创建事务和提交/回滚来释放锁


当然,我可能只是误解了观察到的行为:

所以我在原始代码中注意到,在会话关闭时,数据库上仍然保留着一个锁,因为在对插入的行调用tx.commit时,删除这些行的后续调用没有完成

在添加下面的else块之后,我的测试通过了,我推断这意味着锁已经被释放,因为这些行正在被清理

   Session session = getSessionFactory().openSession();

   MyObject currentState = (MyObject) 
           session.get(MyObject.class, id, 
                       new LockOptions(LockMode.PESSIMISTIC_WRITE));

   if (!statusToUpdateTo.equals(currentState.getStatus())) {
     tx = session.beginTransaction();

     currentState.setStatus(statusToUpdateTo);
     session.save(currentState);

     tx.commit();
   } else {
     // Seems to clear lock
     tx = session.beginTransaction();
     tx.rollback();
   }

   session.close();
对我来说,这显然反映了我对Hibernate的锁定机制缺乏了解,但使用session获得锁似乎有点奇怪。。。或会话。加载。。。然后不使用会话本身释放锁,而是仅通过创建事务和提交/回滚来释放锁


当然,我可能只是误解了观察到的行为:

是的,你想要悲观的。谢谢!很高兴知道我在正确的轨道上。所以我想这引出了另一个问题,那么-锁什么时候释放?我似乎注意到锁在提交时被释放,但奇怪的是,它似乎并没有在会话中被释放。关闭。。。这对我来说没有多大意义-如果您不打算提交[即在我不输入上述if的情况下],那么如何显式释放锁?您通常不会在事务中释放数据库锁,因为您不确定dbs是否通常支持这一点。您需要提交或回滚事务以释放锁。如果您还有其他工作需要继续,那么您可能需要在单独的事务中处理此锁定。这很有意义。。。我想这里的问题是,如果我遵循您的术语,锁是在事务开始之前获得的。我已经能够证明,通过更改上面的代码以包含一个开始并回滚事务的else,锁被释放。但这似乎有点。。。我觉得奇怪。我可能会为我自己的问题添加一个答案,说明我所做的和观察到的。如果您没有在显式控制的事务中获取锁,那么您真的不知道该锁将有效多久。如果您的数据库连接正在使用某种形式的自动提交,您可能会随时失去锁定。是的,您需要悲观的写入。谢谢!很高兴知道我在正确的轨道上。所以我想这引出了另一个问题,那么-锁什么时候释放?我似乎注意到锁在提交时被释放,但奇怪的是,它似乎并没有在会话中被释放。关闭。。。这对我来说没有多大意义-如果您不打算提交[即在我不输入上述if的情况下],那么如何显式释放锁?您通常不会在事务中释放数据库锁,因为您不确定dbs是否通常支持这一点。您需要提交或回滚事务以释放锁。如果您还有其他工作需要继续,那么您可能需要在单独的事务中处理此锁定。这很有意义。。。我想这里的问题是,如果我遵循您的术语,锁是在事务开始之前获得的。我有b
我们甚至能够证明,通过更改上述代码以包含一个开始并回滚事务的else,锁被释放。但这似乎有点。。。我觉得奇怪。我可能会为我自己的问题添加一个答案,说明我所做的和观察到的。如果您没有在显式控制的事务中获取锁,那么您真的不知道该锁将有效多久。如果您的数据库连接使用某种形式的自动提交,您随时可能失去锁定。Hibernate的doco about Session.close:通过释放JDBC连接并清理来结束会话。而且它没有说明任何关于连接的内容,所以当您关闭会话时,是否提交或回滚连接完全取决于连接提供程序。这就是为什么您需要通过TX手动执行此操作。通常,会话是一个工作单元,它可能与基础连接不同步。Hibernate的doco about session.close:通过释放JDBC连接并清理来结束会话。而且它没有说明任何关于连接的内容,所以当您关闭会话时,是否提交或回滚连接完全取决于连接提供程序。这就是为什么您需要通过TX手动执行此操作。通常,会话是您的工作单元,它可能与基础连接不同步。