我很难理解Spring Transactions。首先,我试图尽可能少使用Spring。基本上,我想使用@Transactional及其一些注入功能与JPA / Hibernate。我的交易用法是在我的服务层。我试图让他们远离测试用例。我使用CTW并且是弹簧配置的。我现在正在我的包的根目录上进行组件扫描。我也在为我的数据源,JpaTransactionManager和EntityManagerFactory使用Java配置。我对JpaTransactionFactory的配置使用:
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
我不使用@EnableTransactionManagement。
不幸的是,我很难理解@Transactional的规则,并且找不到简单描述它们的简单页面。特别是关于会话使用。例如,如果我想在没有默认no-arg构造函数的类上使用@Transactional会怎么样?
我遇到的最奇怪的问题是,在某些POJO服务类中,Transacitonal工作得很好,而在其他服务类中,我可以看到正在创建的交易,但操作最终会说“没有会话或会话已经关闭” 。我为没有代码重现这一点而道歉,我无法将其归结为一小部分。这就是为什么我在寻找最好的资源,所以我可以自己解决这个问题。
例如,我可以使用一个方法来获取一个延迟获取的子集合,迭代它并将其放入一个Set并返回该集合。在一个类中,它将正常工作,而在另一个也标有@Transactional的类中,它会在尝试迭代PersistentSet时失败,说没有会话(即使有事务)。
也许这是因为我在测试用例中创建了这两个服务对象,第一个是以某种方式劫持会话?
顺便说一下,我已经阅读了Spring源码的交易文件。我正在寻找一套明确的规则和技巧来调试这样的问题。感谢。
答案 0 :(得分:1)
您确定在您尝试加载懒惰孩子的交易范围内加载了您的父实体吗?如果它作为参数传递(例如,从您的@Transactional
方法之外加载),那么它可能不再被绑定到持久化上下文...
请注意,当没有给出@Transactional
上下文时,任何与数据库相关的操作都可能有一个短tx要创建,然后立即关闭 - 禁用后续的延迟加载调用。这取决于您的persistence context和auto-commit配置。
简而言之,没有交易上下文的行为有时是意料之外的,基本规则是总是有一个。如果您访问数据库,那么您可以为自己定义一个明确定义的tx - 句点。使用spring-tx,表示您的所有@Repository
和@Service
都是@Transactional
。这样你应该避免大多数与tx相关的问题。