有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate会话与线程安全

如何在使用hibernate会话时实现线程安全。在多线程环境中使用会话对数据库执行CRUD操作时,我经常遇到数据库和会话不同步的异常。Mine是一个多线程应用程序,它尝试在另一个用户使用对象一段特定时间时锁定该对象(在锁表中创建条目),然后释放锁(从锁表中删除条目)。我可以使CRUD方法同步吗?如果我可以在多线程环境中执行应用程序时,它会产生什么影响


共 (2) 个答案

  1. # 1 楼答案

    建议的方法是根据请求创建会话并关闭它。不太确定如何设置配置,但如果您查看hibernate developer guide或docs,它将为您提供指导

    例如:

    Session sess = HibernateUtil.getSessionFactory().getCurrentSession();
    sess.beginTransaction();
    

    //您的数据库操作将在此处执行

    sess.update(profile);
    
    sess.getTransaction().commit();
    sess.close();
    
  2. # 2 楼答案

    我想补充一点,我鼓励您使用不同的锁定策略

    当需要高并发性时,行级锁无法很好地扩展。如果请求的行级锁太多,大多数数据库平台最终会将行级锁升级为页级锁或更糟糕的表级锁。这将对性能、并发性和可伸缩性产生巨大影响

    我建议你转而研究乐观锁定

    乐观锁定避免将锁推送到数据库,而是允许持久性提供程序保持这种状态。这是通过提供一个带有@Version注释的字段来实现的,该字段保存一个种子值,该种子值唯一地标识一行的版本状态

    这种方法可以很好地扩展,因为共享资源(数据库)不再阻止针对同一行的并发操作。它还允许对表进行几乎无限的操作,而无需锁并发争用。相反,锁定被委托给持久性提供程序,后者维护这个@Version注释的字段,并可以确定自持久性提供程序上次查询该行以来该行是否已被更改

    简而言之,第一个使用乐观锁定更新行的人获胜,基于第一次更新之前的版本状态的所有后续更新将以OptimisticLockException失败。然后取决于您的代码,您希望如何重试该操作或选择要求用户重新开始