我有一个OSGi包,我在其中声明了一个服务并用蓝图注入了一个事务:
<bean id="MyServiceImpl"
class="com.test.impl.MyServiceImpl">
<jpa:context property="em" unitname="mypu" />
<tx:transaction method="*" value="Required" />
</bean>
<service id="MyService" ref="MyServiceImpl" interface="com.test.api.MyService" />
在这个服务中,我有两个方法,每个方法都在数据库中写入数据,如下所示:
public void createParent() throws MyException {
Parent parent = new Parent();
... // Set parent fields
em.persist(parent);
createChild();
// Checks that could throw MyException
}
public void createChild() throws MyException {
Child child = new Child();
... // Set child fields
em.persist(child);
// Checks that could throw MyException
}
我的问题如下:
em.persist(parent);
和createChild();
之间的createParent方法中抛出运行时异常,则事务回滚(正如我所料)并且父级不会保留在DB中。但是,如果在同一点上我抛出MyException(这是一个已检查的异常),则事务提交并且父持久化。我在Aries mailing list中看到蓝图声明性事务中声明的(已检查)异常不会触发回滚。有没有办法配置此行为并指定我希望我的异常在抛出时回滚事务?em.persist(child);
之后),子数据库中没有持久存在,则父项是持久的,就好像这两个方法在两个不同的事务中运行一样。这是为什么?在createParent启动的事务中不应该createChild join吗?有人可以解释一下上述行为吗?
答案 0 :(得分:1)
从Aries邮件列表中获得一些帮助后,结果表明问题出在数据源配置中,而不是蓝图配置中。虽然我使用MysqlXADataSource
作为驱动程序类,但数据源服务已注册为javax.sql.DataSource
而不是javax.sql.XADataSource
,这正在弄乱我的交易。
答案 1 :(得分:0)
1:几年前我问了同样的问题。在Spring中,您可以指定某些事务应该导致回滚,而有些事务则不会,在蓝图中您无法执行此操作。过了一会儿,我找到了“清洁代码”一书,并阅读了“错误处理”一章。我开悟了。我并没有像书中所说的那样写下来。我想在你阅读之后,如果这是一种正确的行为,你会得到一些有用的基本想法来建立你的意见。
2:可以有两种选择:
3:这也让我感到困惑:)你是否确定在父母坚持但在给孩子打电话之前你没有抛出异常?可能ASM存在,如果那是jta-blueprint有一个bug ...需要调试才能找出发生的事情。
4:很高兴听到它可以以某种方式工作:)