之前撰寫@Transactional 方法間呼叫的回滾範圍時,弄錯了try catch捕捉例外時@Trancsational
的rollback效果。
- Spring Boot 2.3.2.RELEASE
- Spring Data JPA
掛有@Trancsational
的方法若執行時發生例外被try catch捕捉且不再拋出例外,則該方法的交易不會rollback。
例如下面DemoService
有兩個方法皆為新增資料並故意拋出錯誤,差別在於是否有使用try catch捕捉例外錯誤。無捕捉錯誤的方法的交易才會回滾,而有捕捉錯誤的方法則否。
DemoService
@Service
public class DemoService {
@Autowired
private EmployeeRepository employeeRepository;
/** 無try-catch 會觸發@Transactional rollback */
@Transactional
public void addWithoutTryCatch() {
employeeRepository.save(new Employee("John"));
throw new RuntimeException("Save data error!");
}
/** 有try-catch 不會觸發@Transactional rollback*/
@Transactional
public void addWithTryCatch() {
try {
employeeRepository.save(new Employee("John"));
throw new RuntimeException("Save data error!"); // 錯誤被try catch捕捉了
} catch (Exception e) {
}
}
}
測試。
DemoServiceTests
@SpringBootTest
public class DemoServiceTests {
@Autowired
DemoService demoService;
@Autowired
EmployeeRepository employeeRepository;
@Test
void addWithoutTryCatch_rollback() {
try {
demoService.addWithoutTryCatch();
} catch (Exception e) {
}
List<Employee> employeeList = employeeRepository.findAll();
Assertions.assertEquals(0, employeeList.size()); // 有rollback資料未新增
}
@Test
void addWithTryCatch_noRollback() {
demoService.addWithTryCatch();
List<Employee> employeeList = employeeRepository.findAll();
Assertions.assertEquals(1, employeeList.size()); // 無rollback資料有新增
}
}
參考github。
沒有留言:
張貼留言