使用 Spring 的 JPA 的手动事务服务和 DAO 层
我将 JPA 与 Spring 一起使用。如果我让 Spring 处理事务,那么假设 EntityManager 已正确注入到 DAO 中,我的服务层将如下所示:
MyService {
@Transactional
public void myMethod() {
myDaoA.doSomething();
myDaoB.doSomething();
}
}
但是,如果我要手动执行事务,我必须确保传递该实例EntityManager 到事务中的每个 DAO 中。知道如何更好地重构吗?我觉得做 new MyDaoA(em) 或将它们传递到每个 DAO 方法(如 doSomething(em))中很丑。
MyService {
private EntityManagerFactory emf;
public void myMethod() {
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
MyDaoA myDaoA = new MyDaoA(em);
MyDaoB myDaoB = new MyDaoB(em);
try {
tx.begin();
myDaoA.doSomething();
myDaoB.doSomething();
tx.commit();
} catch(Exception e) {
tx.rollback();
}
}
}
I am using JPA with Spring. If I were to let Spring handle the transactions, then this is what my Service layer would look like assuming the EntityManager has been properly injected into the DAOs:
MyService {
@Transactional
public void myMethod() {
myDaoA.doSomething();
myDaoB.doSomething();
}
}
However, if I were to do transactions manually, I have to make sure to pass that instance of EntityManager into each of the DAOs within a transaction. Any idea how can this be better refactored? I fee ugly doing new MyDaoA(em) or passing em into each DAO method like doSomething(em).
MyService {
private EntityManagerFactory emf;
public void myMethod() {
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
MyDaoA myDaoA = new MyDaoA(em);
MyDaoB myDaoB = new MyDaoB(em);
try {
tx.begin();
myDaoA.doSomething();
myDaoB.doSomething();
tx.commit();
} catch(Exception e) {
tx.rollback();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是你错的地方。从Spring参考中, JPA 部分:
This is where you are wrong. From the Spring Reference, JPA section:
将其添加到您的 spring 配置中
,现在您可以在 dao 中使用 @Autowired EntityManager
进行事务管理,因为您已经使用了 spring 和 @Transactional 注释,我假设您已经在 spring.xml 中声明了一个事务管理器,
因此使用 spring 的事务管理
作为
add this to your spring config
now you can @Autowired EntityManager inside your dao
for the transaction management, since you already using spring, and @Transactional annotation, i assume you already have one transaction manager declared in your spring.xml
so using spring's transaction management
as
我猜有点在黑暗中拍摄,但你知道你可以这样做吗:
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
这通常消除了您希望/需要在具有声明性的系统中使用编程式事务的大多数情况交易。
Shot in the dark a bit I guess, but do you know you can do:
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
That usually eliminates the majority of cases where you would want/need to use programmatic transactions in a system that otherwise has declarative transactions.