Java Hibernate使用nolock的HQL查询

11

有没有一种方法可以像为这些查询添加(NOLOCK)提示符一样运行它们?

3个回答

9

如果你确实需要这样做,那么你想要做的是:

session.connection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

这与无锁(nolock)相同。

在这样做之前,请认真考虑是否要进行脏读取。大多数情况下,人们这样做是因为他们一直这样做,而不是因为这是正确的事情。特别地,这与缓存不兼容。

实际上,这个帖子深入探讨了相关问题。请仔细阅读后再决定。


谢谢,Gary。 是的,我正在寻找“脏读取(dirty reads)”。我们的数据库管理员建议在此项目区域中的所有“selects”中使用NOLOCK。问题是,部分SQL语句是Hibernate。 - Sarit
2
在最新版本的Hibernate中,API似乎已经删除了connection()。有什么想法可以在没有connection对象的情况下实现类似的效果吗? - IK.
1
如果您使用@Transactional注释,则可以将其指定为isolation属性。 - Tobb
@Tobb - 明确一下,我假设你是指Spring的事务注解,而这并不是Hibernate的一部分。 - GaryF

7

在最新版本的Hibernate中,您需要按照以下方式执行:

  Session session = (Session) em.getDelegate();
        session.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }
        });

我曾使用这种方法在某些查询上设置了read_uncommitted事务隔离级别,但我意识到连接数量比没有使用该方法时增加了多次。我们的Websphere服务器上应用程序的连接数,在使用read_uncommitted事务之前,一个用户的连接数为4,而在使用之后,它变成了80。这正常吗?还是我应该寻找其他地方和其他方法来解决这个问题? - CntkCtn

3

如果您使用本地方式,可以使用“with (nolock)”选项。这是一种极端的方法,但如果替代方案是更改事务隔离级别,那么您可能更愿意这样做。

请注意,此示例适用于MSSQL。

String sqlQueryString = "SELECT * FROM my_classes_table WITH (nolock) WHERE columnName = :columnValue";

SQLQuery sqlQuery= session.createSQLQuery(sqlQueryString).addEntity(MyClass.class);
sqlQuery.setLong("columnValue", value);
List<MyClass> out = sqlQuery.list();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接