是否可以防止通过Hibernate读取数据库行?

时间:2022-02-09 10:23:04

I have a simple setup of Hibernate 3.6 and MySQL. I want to find out how locking works. My code is here:

我有一个简单的Hibernate 3.6和MySQL设置。我想知道锁定是如何工作的。我的代码在这里:

package hibernate;
import java.util.*;
import org.hibernate.*;
public class HibernateGames {
    public static void main(String[] args) {

        //main transaction
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Message loaded = (Message) session.get(Message.class, 21l);
        session.lock(loaded, LockMode.PESSIMISTIC_WRITE);

        //concurrent transaction
        Session session2 = HibernateUtil.getSessionFactory().openSession();
        Transaction tx2 = session2.beginTransaction();
        Message loaded2 = (Message) session2.get(Message.class, 21l);
        tx2.commit();
        session2.close();

        //main transaction committed
        Message loadedAtLast = (Message) session.get(Message.class, 21l);
        tx.commit();
        session.close();

        HibernateUtil.shutdown():
    }
}
  1. As far as I understand there are 2 main types of locks in every database: exclusive and shared. The first one totally blocks all operations with the row, the second one lets other users read or acquire own shared lock from that row. The first one is set by select.. update statement, the second one is set by select .. lock in share mode or something like this. Is this correct?

    据我所知,每个数据库中有两种主要类型的锁:独占和共享。第一个完全阻止所有行操作,第二个允许其他用户从该行读取或获取自己的共享锁。第一个是由select .. update语句设置的,第二个是由select .. lock在共享模式或类似的东西设置的。它是否正确?

  2. Does it work in a different way under different isolation levels?

    它是否在不同的隔离级别下以不同的方式工作?

  3. My setup doesn't block the concurrent transaction tx2 from reading. Why? How can I achieve this?

    我的设置不会阻止并发事务tx2读取。为什么?我怎样才能做到这一点?

1 个解决方案

#1


0  

I may be wrong, but the article here says that Hibernate will delegate the locking mechanism to DB, so it depends on the isolation level specified on the db. Also, I do not see the LockMode.PESSIMISTIC_WRITE anywhere. You may try to lock it using LockMode.UPGRADE and try to see if it locks.

我可能错了,但是这里的文章说Hibernate会将锁定机制委托给DB,所以它取决于db上指定的隔离级别。另外,我在任何地方都看不到LockMode.PESSIMISTIC_WRITE。您可以尝试使用LockMode.UPGRADE锁定它,并尝试查看它是否锁定。

If you really want to lock the row in the update db operation try to set the isolation to serializable in the hibernate configuration.

如果您确实想要在更新数据库操作中锁定行,请尝试在hibernate配置中将隔离设置为可序列化。

Update: I believe that you are confused with LockMode of JPA and Hibernate,LockMode.PESSIMISTIC_WRITE is jpa thing and it will work with entityManager setup, it may not work with session. try to replace it with lockmode.UPGRADE which is a hibernate static value.

更新:我相信你对JPA和Hibernate的LockMode感到困惑,LockMode.PESSIMISTIC_WRITE是jpa的东西,它可以与entityManager设置一起工作,它可能不适用于session。尝试用lockmode.UPGRADE替换它,这是一个休眠静态值。

#1


0  

I may be wrong, but the article here says that Hibernate will delegate the locking mechanism to DB, so it depends on the isolation level specified on the db. Also, I do not see the LockMode.PESSIMISTIC_WRITE anywhere. You may try to lock it using LockMode.UPGRADE and try to see if it locks.

我可能错了,但是这里的文章说Hibernate会将锁定机制委托给DB,所以它取决于db上指定的隔离级别。另外,我在任何地方都看不到LockMode.PESSIMISTIC_WRITE。您可以尝试使用LockMode.UPGRADE锁定它,并尝试查看它是否锁定。

If you really want to lock the row in the update db operation try to set the isolation to serializable in the hibernate configuration.

如果您确实想要在更新数据库操作中锁定行,请尝试在hibernate配置中将隔离设置为可序列化。

Update: I believe that you are confused with LockMode of JPA and Hibernate,LockMode.PESSIMISTIC_WRITE is jpa thing and it will work with entityManager setup, it may not work with session. try to replace it with lockmode.UPGRADE which is a hibernate static value.

更新:我相信你对JPA和Hibernate的LockMode感到困惑,LockMode.PESSIMISTIC_WRITE是jpa的东西,它可以与entityManager设置一起工作,它可能不适用于session。尝试用lockmode.UPGRADE替换它,这是一个休眠静态值。