澄清Hibernate中的Read和None LockMode?

时间:2011-11-15 03:43:33

标签: hibernate transactions

根据Hibernate docs中的Read LockMode 这是一个共享锁。处于此锁定模式的对象是从当前事务中的数据库中读取的,而不是从缓存中提取的。

     SessionFactory sessions = new Configuration().configure().buildSessionFactory();
     Session session = sessions.openSession();
     Transaction tx = null;
        tx = session.beginTransaction();
        Person p1  = (Person)session. get(Person.class,1);//line 1
         p1  = (Person)session. get(Person.class,1);//line 2
         session. lock(p1, LockMode.READ);//line 3
         p1  = (Person)session. get(Person.class,1);//line4 
         p1  = (Person)session. get(Person.class,1);//line 5

现在根据共享锁定义持有共享锁以防止编写者使用上面的代码片段进行并发访问,我将线程保留在第4行(因此它已获取读取锁定此时的模式)。现在我尝试从另一个线程更新id为1的人,它成功了。不确定原因,因为按照定义持有共享锁以防止作者并发访问

正如读取锁定模式所示此锁定模式下的对象是从当前事务中的数据库中读取的,而不是从缓存中提取。在第4行和第5行的代码片段中,它没有从数据库获取id为1的行,它仅来自会话。为什么?

无锁模式的最后一个问题。根据文档不需要锁定。如果使用此锁定模式请求对象,则如果需要从数据库中实际读取状态而不是从缓存中提取状态,则将获得READ锁定。如上所述,没有获取锁定,那么为什么开发人员获取此锁定,因为这将是默认的。 从右吗

1 个答案:

答案 0 :(得分:2)

  

现在我尝试从另一个线程更新id为1的人   成功了。不确定为什么,因为根据定义持有共享锁定   防止作者并发访问

当一个线程1要将一个实体写入数据库并且线程2要从中读取同一个实体时,怎么样?其中任何一个都应该获得锁定来读取或写入数据。如果thread1获得写锁定,则线程2必须等到写入完成。但是,如果线程2获得读锁定,则线程1在进入和写入数据时没有问题。这是因为当线程2以一致状态读取记录时。只有在线程1写入数据库之后它才会变得陈旧(虽然,在版本化实体的情况下,从线程2写入此对象将触发陈旧状态异常)。读锁用于防止不一致,并且不会冻结记录以供同一事务进一步更新。您可以使用写锁来实现该行为。

  

无锁模式的最后一个问题。根据文件无锁   需要。如果使用此锁定模式请求对象,则执行READ锁定   如果有必要从中实际读取状态,将获得   数据库,而不是从缓存中提取它。如上所述没有锁定   获得了为什么开发者会获得这个锁,因为这样   默认。正确?

再次获取读锁定以防止实体处于不一致状态。从缓存中它不会是一个问题。开发人员在进行提取时不需要指定Read锁,它应该由持久性提供程序在内部进行管理。