我有两个模特班:模特
2个持久类:ModelADAO
public class ModelADAOImpl implements ModelADAO {
public bool save(modelA) {
try {
session = this.sessionFactory.openSession();
transaction = session.beginTransaction();
...
session.persist(modelA);
...
transaction.commit();
} catch(Exception e) {
transaction.rollback();
} finally {
session.close();
}
}
}
public class ModelBDAOImpl implements ModelBDAO {
public bool save(modelB) {
try {
session = this.sessionFactory.openSession();
transaction = session.beginTransaction();
...
session.persist(modelB);
...
transaction.commit();
} catch(Exception e) {
transaction.rollback();
} finally {
session.close();
}
}
}
现在,我有了另一个带有saveAll(modelA,modelB)方法的类,通过调用modelADAO.save(modelA)和modelBDAO.save(modelB)来保存modelA和modelB的信息。
public class WrapperDAOImpl implements WrapperDAO {
@Autowired
private ModelADAO modelADAO;
@Autowired
private ModelBDAO modelBDAO;
public bool saveAll(modelA, modelB) {
try {
...
modelADAO.save(modelA);
modelBDAO.save(modelB);
...
} catch(Exception e) {
...
} finally {
...
}
}
}
在这种情况下,如何应用saveAll(型号A、型号B)的回滚?因为我在每个save()方法中都打开和关闭了会话。
谢谢
特朗。
我建议你改变你造刀的方式。我从不在DAO内部进行事务管理,而是在服务层管理事务。
一个服务方法需要调用几个DAO方法是很常见的,因此您希望对所有方法应用一个事务,就像您在问题中提到的那样。
因此,我将事务管理移动到saveAll
方法。显然,如果DAO保存方法在不管理事务的情况下调用,此更改可能会导致错误。这就是为什么我告诉您使用服务层。
另一种选择,将事务管理留在DAO中,可以使用事务传播,PROPAGATION=必需
。然而,我从未使用过它,也不知道它是如何工作的,但至少理论上应该这样,如果在调用保存
方法时没有创建事务,它将被创建,但如果有一个已经创建的事务,它将使用它。回滚将撤消所有更改。
大多数框架应用的典型解决方案是逐线程跟踪正在运行的事务,因此您可以将线程保持在正在运行事务的本地。另一种解决方案是将tx作为参数传递给方法。
您必须使用通用接口来保存数据,而不是依赖于entityA或entityB。对于您的模型,您必须有一个包含id的基本bean。
public class BaseBean{
private Long id ;
//get + set
}
public class Aa extends BaseBean{
}
public class Bb extends BaseBean{
}
public interface daoRepository{
<T extends BaseBean> void save(Iterable<? extends T> objects);
}
public class daoImpl implements daoRepository{
@Override
public <T extends BaseBean> void save(Iterable<? extends T> objects){
try {
session = this.sessionFactory.openSession();
transaction = session.beginTransaction();
...
for (T t : objects) {
session.persist(t);
}
...
transaction.commit();
} catch(Exception e) {
transaction.rollback();
} finally {
session.close();
}
}
}