Hibernate:强制'使用(NOLOCK)'提示所有选择查询,而不更改隔离级别

时间:2016-05-03 15:24:46

标签: java sql-server hibernate isolation-level nolock

快速背景故事:

我处理的是一个非常旧的应用程序,该应用程序最近一直存在数据库锁定问题。该应用程序是用Java编写的,并使用Hibernate。我们发现的其中一个问题是,事务处理的异常长时间保持活动状态,同时还经常在READ_COMMITED和READ_UNCOMMITED之间更改隔离级别。虽然我们承认明确的解决方案是重构代码以便交易更小,但这将是我们现在无法承担的巨大努力(应用程序的大多数使用部分正在迁移到新系统,但此过程相对较慢)。

所以 - 因为我们对所有Select操作使用READ_UNCOMMITED而对其他所有操作都使用READ_COMMITED,一直在帮助我们的DBA,确定了将隔离级别更改为全局READ_COMMITED并更改所有选择查询以包含提示的可能解决方案'与(NOLOCK)'。他说功能上检索数据的方式应该没有区别(因为我们现在使用脏读没有问题),同时为我们提供了不必频繁更改事务中隔离级别的优势。我相信他的想法也是关于我们最近关于数据库锁由隔离级别变化引起的报告。

所以 - 我们可以(如果是这样,怎么做?)告诉hibernate在使用映射的java对象和HQL(甚至现有的SQL传递)自动生成的所有查询中添加'with(nolock)'提示休眠,虽然这似乎推动它:))没有改变隔离级别?

最后的注意事项:我们正在使用旧版本的hibernate,v3.5,现在升级的可能性不大,一些令人难以置信的“聪明”的人决定在某些时候将其污染,插入一些自己的应用程序代码使用。已尝试升级并多次失败。

另外:我已经检查了很多相关的线程,一般的想法似乎是:不要使用nolock,更改隔离级别,如上所述 - 我们不打算这样做。

Edit1:由于应用程序在过去12年中不断发展,有许多模块甚至没有被当前的开发团队一瞥,理想的解决方案是不需要的识别使用持久对象的每一段Java代码。

Edit2:一种可行的方法 - 应该是Hibernate允许它 - 将添加一种Interceptor形式,在传递给db驱动程序之前接收格式化的SQL查询。然后我会使用某种形式的正则表达式自己添加提示。

非常感谢你。

1 个答案:

答案 0 :(得分:0)

你不能在HQL中使用(NOLOCK)。但是,如果您决定更改查询,则可以使用本机SQL。类似的东西:

getCurrentSession().createSQLQuery("select * from table with(NOLOCK)").list();