@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'的事务块)中发生任何异常时,为什么没有在调用者类中对其进行处理(具有具有默认传播行为的事务块)?而不是看到消息“夹在Impl类的doOperationOnMetadata内部”,而是收到消息“夹在Controller类的callServiceMethod内部”。
答案 0 :(得分:0)
如果问题在于在外部方法是否可以在外部方法上发生事务回滚,那么底层方法是否存在异常,则对于Propagation为REQUIRES_NEW的回答是否定的,因为每种方法都将被视为独立事务。
参考-@Transactional(propagation=Propagation.REQUIRED)和https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html#tx-propagation