【发布时间】:2013-01-29 01:18:19
【问题描述】:
我很难理解 Spring Transactions。首先,我试图尽可能少地使用 Spring。基本上,我想在 JPA/Hibernate 中使用 @Transactional 和它的一些注入功能。我的事务使用在我的服务层。我试图将它们排除在测试用例之外。我使用 CTW 并且是弹簧配置的。我现在对我的包的根目录进行了组件扫描。我还在为我的数据源、JpaTransactionManager 和 EntityManagerFactory 使用 Java 配置。我对 JpaTransactionFactory 的配置使用:
AnnotationTransactionAspect.aspectOf().setTransactionManager( txnMgr );
我不使用@EnableTransactionManagement。
不幸的是,我很难理解@Transactional 的规则,也找不到简单描述它们的简单页面。特别是关于会话使用。例如,如果我想在没有默认无参数构造函数的类上使用 @Transactional 怎么办?
我遇到的最奇怪的问题是,在某些 POJO 服务类中,Transacitonal 工作得很好,而在其他服务类中,我可以看到正在创建的事务,但操作最终会说“没有会话或会话已关闭” .我很抱歉没有代码来重现这个,我不能把它缩小到一个小集合。这就是为什么我正在寻找最好的资源,以便我自己弄清楚。
例如,我可以有一个方法来获取延迟获取的子集合,对其进行迭代并将其放入 Set 并返回该集合。在一个类中它可以正常工作,而在另一个也标有 @Transactional 的类中它会在尝试遍历 PersistentSet 说没有会话(即使存在事务)时失败。
也许这是因为我在测试用例中创建了这两个服务对象,而第一个以某种方式劫持了会话?
对了,我已经通读了spring源码的事务文档。我正在寻找一套清晰的规则和提示来调试此类问题。谢谢。
【问题讨论】:
-
Spring 提供了三种检测类的方法:DynamicProxy(仅限接口)、cglib 或 AspectJ。 . .如果您不使用 AspectJ weaving,并且您想将事务注释添加到普通类(不是接口),它将默认为 cglib。 cglib 需要一个默认的 ctor。
-
我还应该指出,事务管理似乎在任何地方都运行良好。这个抛出无会话异常的地方就是它需要执行延迟加载的地方。我正在将一对多的集合加载到另一个集合中。它全部包含在 @Transactional 方法中,因此应该有一个活动会话。我只返回填充的 HashSet。基本上,这是在事务方法“return new HashSet(parent.getChildren());”中进行的。不确定会话发生了什么。我会看看我是否可以创建一个小的可重复测试。
-
@JasperBlues 上面我的 Java 配置中的那一行不会导致它使用 AspectJ 编织作为事务注释吗?被传递的 txnMgr 是通常的 JpaTransactionManager。那里没什么特别的。
-
不,我不这么认为。要打开 AspectJ,您还需要执行 1) 编译时编织 - Ant/Maven/Cmd-line/IDE 任务或 2) 运行时编织 - 需要指向 AspectJ jar 文件的 JVM -javaagent 的特殊参数。
-
@JasperBlues,我肯定在使用 AJC 和 CTW。