Hibernate grails中withTransaction和withSession的区别是什么?

Hibernate grails中withTransaction和withSession的区别是什么?,hibernate,session,grails,transactions,gorm,Hibernate,Session,Grails,Transactions,Gorm,我知道一个获取底层会话,另一个获取当前事务状态的引用;然而,它们之间的区别是什么?每一个的示例用例是什么 我的要求是在服务方法块中批量保存一些记录。这是两件完全不同的事情。会话是一种抽象,允许您访问所有hibernate功能,而TransactionStatus可用于控制当前事务 如果您需要直接访问hibernate功能,可以使用带会话的。如果您想使用Grails/GORM不直接支持的hibernate功能,这可能会很有用。withTransaction有点不成熟,因为它允许您在任何地方进行事务

我知道一个获取底层会话,另一个获取当前事务状态的引用;然而,它们之间的区别是什么?每一个的示例用例是什么

我的要求是在服务方法块中批量保存一些记录。

这是两件完全不同的事情。会话是一种抽象,允许您访问所有hibernate功能,而TransactionStatus可用于控制当前事务


如果您需要直接访问hibernate功能,可以使用带会话的
。如果您想使用Grails/GORM不直接支持的hibernate功能,这可能会很有用。

withTransaction
有点不成熟,因为它允许您在任何地方进行事务性工作,但最好将您的关注点分离出来,并在事务性服务中进行工作。默认情况下,服务是事务性的,除非您添加
static transactional=false
,并且可以使用
@transactional
注释在类和/或方法级别进行微调。只需将代码放入服务方法中,而不使用
with transaction
with session
,就可以了

with Session
是访问当前Hibernate
会话
的便捷方式(通常是由OpenSessionInView拦截器注册的会话)。如果您想清除会话,或执行GORM未公开的其他工作,这是一种访问会话的方法,而无需访问
sessionFactory
或Spring使用的线程本地保持器


在事务服务方法之外使用
withTransaction
的一个有效方法是在控制器请求之外绑定Hibernate
会话
(即没有自动创建的
会话
withTransaction
将启动一个事务,并在需要时创建一个
会话
,并在关闭期间保持打开状态。因此,您可以使用它来避免延迟加载异常。我们需要另一种方法来做到这一点,而不需要事务开销,对于那些只需要从数据库读取而不需要事务写入的情况。但就目前而言,这种方法是有效的。但是,如果您进行数据库写入,请将代码移动到服务方法。

谢谢Burt。我正在批处理记录,发现我需要
with session
快捷方式,因为调用
sessionFactory.getCurrentSession().clear()
变得单调乏味。这个答案严格来说不是真的。在许多情况下,您希望在服务中回滚,而不向调用方抛出异常。在这种情况下,唯一的选择是使用withTransaction。除非您真的处于异常状态,否则您几乎永远不会希望回滚带有异常的事务。使用未检查异常回滚事务的典型反模式利用了副作用,并且由于异常的代价而效率低下,使用Groovy时更是如此。但是
withTransaction
并不是唯一正确的方法。只要使用
TransactionSpectSupport.currentTransactionStatus().setRollbackOnly()
Burt你就是那个人!我正在寻找一种不使用withTransaction即可获取TransactionStatus的方法。谢谢事实上,我在Grails2.5.1上尝试了这一点,但失败了,例外情况是范围内没有事务方面管理的TransactionStatus。然而还有另一种解决方案,在@Transactional注释的方法中,我看到有一个神奇的注入变量transactionStatus在运行时。你可以用这个。