@Controller
public class MyControllerClass{
@Autowired
private MyService service;
public SomeResponse callServiceMethod(SomeRequest reqObj){
try{
//lines of codes
service.serviceMethod(reqObj);
//lines of codes
} catch(Exception ex){
S.O.P("caught inside callServiceMethod of Controller
class");
}
}
public interface MyService{
SomeResponse serviceMethod(SomeRequest reqObj);
}
@service
public class MyServiceImpl implements MyService{
@Autowired
private EmployeeDAO empDAO;
@Autowired
private PersonDAO personDAO;
@Autowired
private MetadataDAO metaDAO;
@Transactional(value="transaction_manager_Bean_Name")
public SomeResponse serviceMethod(SomeRequest reqObj){
List<Person> personList = ....;//fetch list of person from
//reqObj
List<Employee> empList = ......;//fetch list of Employee
//from reqObj
SomeHelper someHelper = new SomeHelper(empDAO, personDAO,
metaDAO);
try{
doOperationOnPerson(...);
doOperationOnEmployee(...);
doOperationOnMetadata(...);
} catch(Exception ex){
S.O.P("caught inside serviceMethod of Impl class");
}
}
@Transactional(value="transaction_manager_Bean_Name")
public void doOperationOnPerson(List<Person> personList,
List<String> personErrors, SomeHelper someHelper){
personList.stream().forEach(person ->{
try{
someHelper.performTaskOnPerson(person, personErrors);
} catch(Exception ex){
S.O.P("caught inside doOperationOnPerson of Impl
class");
personErrors.add(ex.getMessage());
}
}
}
@Transactional(value="transaction_manager_Bean_Name")
public void doOperationOnEmployee(List<Employee> empList,
List<String> empErrors, SomeHelper someHelper){
empList.stream().forEach(emp ->{
try{
someHelper.performTaskOnEmployee(emp, empErrors);
} catch(Exception ex){
S.O.P("caught inside doOperationOnEmployee of Impl
class");
personErrors.add(ex.getMessage());
}
}
}
@Transactional(value="transaction_manager_Bean_Name")
public void doOperationOnMetadata(SomeOtherData metadata,
List<String> metaDataList, SomeHelper someHelper){
empList.stream().forEach(emp ->{
try{
someHelper.performTaskOnMetaData(metadata,
metaDataList);
} catch(Exception ex){
S.O.P("caught inside doOperationOnMetadata of Impl
class");
personErrors.add(ex.getMessage());
}
}
}
}
public class SomeHelper{
private PersonDAO personDAO;
private EmployeeDAO empDAO;
private MetadataDAO metaDAO;
SomeHelper(PersonDAO personDAO, EmployeeDAO empDAO, MetadataDAO
metaDAO){
this.personDAO = personDAO;
this.empDAO = empDAO;
this.metaDAO = metaDAO;
}
@Transactional(value="transaction_manager_Bean_Name",
propagation=Propagation.REQUIRES_NEW)
public void performTaskOnEmployee(Employee emp, List<String>
empErrors){
EmpEntity empEntity = empDAO.getEmployee(emp);
empEntity.setName(...);
//update other fields
}
@Transactional(value="transaction_manager_Bean_Name",
propagation=Propagation.REQUIRES_NEW)
public void performTaskOnEmployee(Person person, List<String>
personErrors){
PersonEntity perEntity = personDAO.getPerson(person);
perEntity.setName(...);
//update other fields
}
@Transactional(value="transaction_manager_Bean_Name",
propagation=Propagation.REQUIRES_NEW)
public void performTaskOnMetaData(SomeOtherData metadata,
List<String> metaDataList){
MetaEntity metaEntity = metaDAO.getOther(metadata);
metaEntity.setName(...);
//update other fields
}
}
当somehelper类中的任何方法(将传播行为设置为“requires_new”的事务块)中出现某些异常时,为什么调用方类中不处理它(具有默认传播行为的事务块)?我看到的不是消息“catch inside doOperationMetadata of Impl class”,而是消息“catch inside callServiceMethod of Controller class”。
如果问题是如果基础方法中存在异常,事务回滚是否可以在外部方法中发生,那么对于传播REQUIRES_NEW答案是否定的,因为每个方法都将被视为独立的事务。
引用-@Transactional(传播=传播。必需)和https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html#tx-繁殖
本文向大家介绍浅谈Spring事务传播行为实战,包括了浅谈Spring事务传播行为实战的使用技巧和注意事项,需要的朋友参考一下 Spring框架提供了事务管理的标准实现,且可以通过注解或者XML文件的方式声明和配置事务。 通过异步事件的方式解耦服务调用,可以提高程序的响应速度,并且避免因为事务传播行为而导致的事务问题。 本文以一个电商平台包裹出库的业务为实际背景,通过异步事件与线程池的方式解耦嵌套
我试图理解Spring事务概念。如下所示,我必须将数据插入两个不同的数据库(iSeries和DB2),但我们的iSeries版本不支持两阶段提交。要求是,只有当两个插入都成功时才应该提交事务,否则应该回滚。 如果我根据需要使用传播或REQUIRES\u NEW,我会得到错误“非法尝试使用现有的两阶段资源提交一阶段资源”。 但是如果我使用NOT_SUPPORTED或支持,它工作正常(即如果其中一个插
所称的刀是: 我希望服务类中的方法在事务中运行,并在方法出现异常时回滚所有内容。但这不是在事务中运行的。 如果我将添加到DAO方法中,那么它看起来就像是在单独的事务中运行的。这是正确的吗?
在下面的文章中说, 在此处输入链接描述 需要传播–支持当前交易;如果不存在,请创建一个新的。 下面是一个产品代码,然后是两个表的产品详细信息。 我的问题是什么时候会发生这种行为?我的意思是,当前交易怎么会结束?是在保存还是更新之后? 如果我们使用PROPAGATION_REQUIRED假设当前事务在插入产品后结束。然后一个新的事务来了,但是如果插入产品数量时出现任何故障,它只会回滚数量而不是输入的
在以下代码方法中,更新正确的sql,但sql有一些问题,但是,当我调用doService()时,它必须将更新提交到DB,即使doService 2()有sql异常,因为doService 2()有一个新的传播类型,但是当我取消这个更新时,不会提交DB。。 正如你们的建议,以以下方式进行测试,但仍然面临相同的问题。这里i在一个单独的类中,但即使仍然存在与上述相同的问题
我正在查看一些现有的代码,并想知道在下面的场景中使用Spring的@Transactional注释会发生什么?考虑以下示例: 下面的updateDataBaseItem()方法是常见的,可以从其他非事务性方法和上面的方法调用: