我正在将 Spring 与 Hibernate 一起使用。我有一些实际上不需要事务的查询,但我正在使用一个,因为它为我进行会话管理。在不进行我自己的会话管理的情况下执行这些非事务性读取查询的正确方法是什么?
2 回答
我认为 @Transaction(readOnly=true)是正确的方法。这不会创建新的/额外的物理事务,因此使用它不应该有任何开销。它将使用已经为请求设置的事务。根据休眠文档:
...事实上,每个 SQL 语句,无论是查询还是 DML,都必须在数据库事务中执行。在数据库事务之外不能与数据库通信。(请注意,如果数据库引擎不够聪明,无法优化自己的操作,则可以使用只读事务之类的东西来提高清理时间。)
https://community.jboss.org/wiki/SessionsAndTransactions#Transactions
没有数据库事务是无法工作的(嗯,有,但是驱动程序支持 NO_TRANSACTION 模式(如 DB2 驱动程序)是一种罕见的情况)。此外,驱动程序和数据库可能不支持只读事务(如 Oracle)。所以即使底层连接设置为只读模式,也不代表它会生效。
在这种情况下,唯一可以确定只读标志的是它将 Hibernate 的刷新模式设置为 MANUAL。这意味着 Hibernate 不会与数据库同步,除非发出对 Session#flush() 的显式调用。因此,事务结束时不会发出脏检查和插入/更新/选择。
有关事务管理的更精确信息,您可以查看org.springframework.orm.hibernate3.HibernateTransactionManager#doBegin()
方法。