我很难理解 Spring Transactions。首先,我试图尽可能少地使用 Spring。基本上,我想在 JPA/Hibernate 中使用 @Transactional 及其一些注入(inject)功能。我的交易使用在我的服务层。我尽量让他们远离测试用例。我使用 CTW 并且是 Spring 配置的。我现在对我的包的根进行组件扫描。我还为我的数据源、JpaTransactionManager 和 EntityManagerFactory 使用 Java 配置。我对 JpaTransactionFactory 的配置使用:
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
我不使用@EnableTransactionManagement。
不幸的是,我很难理解@Transactional 的规则,也找不到简单的页面来简单地描述它们。特别是关于 Session 的使用。例如,如果我想在没有默认无参数构造函数的类上使用 @Transactional 怎么办?
我遇到的最奇怪的问题是,在某些 POJO 服务类中,Transacitonal 工作得很好,而在其他类中,我可以看到正在创建的事务,但操作最终失败,说“没有 session 或 session 已关闭” .对于没有代码来重现这一点,我深表歉意,我无法将其缩小到一个小集合。这就是为什么我正在寻找最好的资源,以便我自己弄清楚。
例如,我可以有一个方法来获取延迟获取的子集合,遍历它并将其放入一个集合中并返回该集合。在一个类中它会工作正常,而在另一个也标有@Transactional 的类中它会在尝试遍历 PersistentSet 时失败,说没有 session (即使有一个事务)。
也许这是因为我在测试用例中创建了这两个服务对象,而第一个以某种方式劫持了 session ?
对了,spring的源码事务文档我都看过了。我正在寻找一套清晰的规则和提示来调试此类问题。谢谢。
最佳答案
您确定您在尝试加载惰性子实体的事务范围内加载了您的父实体吗?例如,如果它作为参数传入(即,从 @Transactional
方法外部加载),那么它可能不再绑定(bind)到持久性上下文...
请注意,当未提供 @Transactional
上下文时,任何与数据库相关的操作都可能会创建一个简短的 tx,然后立即关闭 - 禁用后续的延迟加载调用。这取决于你的 persistence context和 auto-commit配置。
简而言之,没有事务上下文的行为有时会出乎意料,基本规则是始终有一个。如果您访问您的数据库,那么您就给了自己一个明确定义的交易周期。对于 spring-tx,这意味着您所有的 @Repository
和 @Service
都是 @Transactional
。这样您应该可以避免大多数与 tx 相关的问题。
关于java - 奇怪的 Spring 事务行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14574125/