我有2个模型类:ModelA& ModelB
2个持久类:ModelADAO& ModelBDAO。在它的每个实现中,我确实使用事务回滚来保存(模型)方法。基本如下:
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) 方法来保存 modelA 和 modelB <的信息/ strong>通过调用 modelADAO.save(modelA) 和 modelBDAO.save(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(modelA,modelB)应用回滚?因为我在每个save()方法中都打开并关闭了会话。
谢谢!
仲
答案 0 :(得分:1)
我建议你改变构建DAO的方式。我从不在DAO内部进行交易管理,而是在服务层管理交易。
通常,服务方法需要调用几个DAO的方法,因此您希望为所有人应用单个事务,正如您在问题中所述。
因此,我将事务管理转移到saveAll
方法。显然,如果DAO保存方法在不管理事务的情况下调用,则此更改可能会导致错误。这就是我告诉你使用服务层的原因。
将事务管理留在DAO中的另一个选择可能是使用PROPAGATION=required
的事务传播。但是我从未使用它并且不确定它是如何工作的,但至少在理论上它应该是这样的,如果在调用save
方法时没有创建事务,它将被创建,但是如果有一个已经创建的交易,它将使用它。回滚将撤消所有更改。
答案 1 :(得分:0)
大多数框架适用的典型解决方案是按线程跟踪正在运行的事务,因此您将保持与正在运行的事务的线程本地。另一个解决方案是将tx作为参数传递给你的方法。
答案 2 :(得分:0)
您必须使用通用接口来保存您的数据,而不是依赖于entityA或entityB。而且对于您的模型,您必须拥有一个包含id的Base 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();
}
}
}