【发布时间】:2015-09-29 07:27:33
【问题描述】:
假设我通过使用@transactions 注释来使用JPA。
所以要让任何方法在事务下运行,我添加了一个@transaction 注释,然后我的方法在事务下运行。
要实现上述目标,我们需要为类提供interface,并且实例由某个容器管理。
此外,我应该始终从接口引用调用该方法,以便代理对象可以启动事务。
所以我的代码看起来像:
class Bar {
@Inject
private FooI foo;
...
void doWork() {
foo.methodThatRunUnderTx();
}
}
class FooImpl implements FooI {
@Override
@Transaction
public void methodThatRunUnderTx() {
// code run with jpa context and transaction open
}
}
interface FooI {
void methodThatRunUnderTx();
}
很好
现在假设methodThatRunUnderTx 做了两个逻辑运算
[1] 调用一些服务(长请求/响应周期,比如说 5 秒)并获取结果
[2] 执行一些jpa实体修改
现在由于这个方法调用很长,我们不想让事务长时间保持打开状态,所以我们更改代码,使 [2] 发生在单独的 tx 中,methodThatRunUnderTx 不会在事务中运行
所以我们将从methodThatRunUnderTx 中删除@Transaction 并在类中添加另一个方法@transaction 假设新方法是methodThatRunUnderTx2,现在要从methodThatRunUnderTx 调用此方法,我们必须将其注入本身并为接口添加一个方法,以便通过代理对象进行调用。
所以现在我们的代码如下所示:
class Bar {
@Inject
private FooI foo;
...
void doWork() {
foo.methodThatRunUnderTx();
}
}
class FooImpl implements FooI {
@Inject
private FooI self;
@Override
//@Transaction -- remove transaction from here
public void methodThatRunUnderTx() {
...
self.methodThatRunUnderTx2();// call through proxy object
}
@Override
@Transaction //add transaction from here
public void methodThatRunUnderTx2() {
// code run with jpa context and transaction open
}
}
interface FooI {
void methodThatRunUnderTx();
void methodThatRunUnderTx2();
}
现在的问题
我们已通过interface 将methodThatRunUnderTx2() 公开。
但这不是我们想要公开为 FooI 的 api 的,也不打算从外部调用..
有什么解决办法吗?
【问题讨论】:
标签: java dependency-injection transactions annotations jpa-2.0