如何使用@transactional
关闭自动提交并进行显式提交?
我有多个操作,我希望它们在完成所有选择和更新后得到提交。选择的原因是基于某些字段为空而完成,并且在某处使用此数据,然后对某些记录进行更新。因此,在新记录出现之前,我必须将字段更改为某个值并避免选择新数据,即仅选择那些已更新的记录
答案 0 :(得分:3)
您只需要将@Transaction注释放在要提交的所有工作中:
@Autowired
private Manager1 manager1;
@Autowired
private Manager2 manager2;
@Transactional
public void doStuff() {
manager1.do();
manager2.do();
}
方法doStuff()中的所有内容都将一起提交,除非抛出异常,在这种情况下它将全部回滚。
答案 1 :(得分:0)
我建议您在这种情况下使用Programmatic方法。
程序化事务管理这意味着您可以在编程的帮助下管理事务。这为您提供了极大的灵活性,但很难维护。
VS
声明式事务管理:这意味着您将事务管理与业务代码分开。您只能使用注释或基于XML的配置来管理事务。
也许是程序化交易管理的替代方式。 例如。
/** DataSourceTransactionManager */
@Autowired
private PlatformTransactionManager txManager;
public void yourMethod() {
try {
// Start a manual transaction.
TransactionStatus status = getTransactionStatus();
your code...
.....
.....
//your condition
txManager.commit(status);
//your condition
txManager.rollback(status);
} catch (YourException e) {
//your condition
txManager.rollback(status);
}
}
/**
* getTransactionStatus
*
* @return TransactionStatus
*/
private TransactionStatus getTransactionStatus() {
DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
dtd.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
dtd.setReadOnly(false);
return txManager.getTransaction(dtd);
}
注意:这并不意味着您需要始终使用像Programmatic事务管理这样的方法。我更喜欢混合方法。对于简单的数据库服务,请使用声明式事务等简单方法,否则,只需在服务中使用Programmatic事务进行控制即可轻松保存逻辑。