Spring可以使用注解进行事务管理,但很多时候,会出现事务不起作用,无法实现我们想要的效果。在众多博客和资料中搜集,@Transactional失效的常见场景主要如下:
1:@Transactional必须要写在public修饰符修饰的方法;private protected等修饰符的方法无法起作用;
2:@Transactional的调用发起方不能是同一类;
3:@Transactional通常不要去手动捕获异常,一旦捕获,则极有可能无法触发回滚操作。
另外,还有事务传播配置、事务异常回滚配置等都会产生影响。在此不做详细说明。
为了更进一步验证方法调用过程中的事务回滚情况。简单编写了几个示例。其结果如下:
情况一:
同类调用:
一:入口方法不写@Transactional。被调用方法写。异常出现在被调用方法。结论:插入和更新都会成功,不会回滚。例子如下:
public void testSW() {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
二:入口方法不写@Transactional。被调用方法写。异常出现在入口方法。结论:插入和更新都会成功,不会回滚。例子如下:
public void testSW() {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
int a = 10/0;
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
三:入口方法写@Transactional。被调用方法也写。异常出现在被调用方法。结论:插入和更新都不会成功,例子如下:
@Transactional
public void testSW() {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
四:入口方法写@Transactional。被调用方法也写。异常出现在入口方法。结论:插入和更新都不会成功,例子如下:
@Transactional
public void testSW() {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
int a = 10/0;
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
五:入口方法写@Transactional。被调用方法也写。异常出现在被调用方法。入口方法进行try catch捕获异常。结论:插入和更新都会成功,不会回滚,例子如下:
@Transactional
public void testSW() {
try {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
六:入口方法写@Transactional。被调用方法也写。异常出现在入口方法。入口方法进行try catch捕获异常。结论:插入和更新都会成功,不会回滚,例子如下:
@Transactional
public void testSW() {
try {
insertBatch(buildInsertPrimary());
updateBatch(buildUpdatePrimary());
int a = 10/0;
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
情况二:
异类调用:
七:入口方法不写@Transactional。被调用方法写。异常出现在被调用方法。结论:插入可以成功,更新不会成功。例子如下:
public void testSW() {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
八:入口方法不写@Transactional。插入方法写,更新方法不写。异常出现在被调用方法。结论:插入和更新都会成功。例子如下:
public void testSW() {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
九:入口方法不写@Transactional。被调用方法写。异常出现在入口方法。结论:插入和更新都会成功。例子如下:
public void testSW() {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
int a = 10/0;
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
十:入口方法不写@Transactional。被调用方法写。异常出现在入口方法,且捕获住异常。结论:插入和更新都会成功。例子如下:
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
int a = 10/0;
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
十一:入口方法不写@Transactional。被调用方法写。异常出现在被调用方法,且捕获住异常。结论:插入成功,更新不成功。例子如下:
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
十二:入口方法不写@Transactional。插入方法写,更新方法不写。异常出现在被调用方法,且捕获住异常。结论:插入和更新成功。例子如下:
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
十三:都写上@Transactional 异常出现在被调用方法或者入口方法,结论:插入和更新不成功,例子如下:
@Transactional
public void testSW() {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
十四:都写上@Transactional 异常出现在被调用方法,且捕获住异常,结论:插入和更新不成功,且报错信息为:Transaction rolled back because it has been marked as rollback-only 例子如下:
@Transactional
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int a = 10/0;
}
十五:都写上@Transactional 异常出现在入口方法,且捕获住异常,结论:新增和更新都成功 例子如下:
@Transactional
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
int a = 10/0;
}catch(Exception e) {
System.out.println("捕获异常");
}
}
@Transactional
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
@Transactional
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
}
十六:入口方法写上@Transactional 异常出现在被调用方法上或者在入口方法上。结论:新增和更新都不成功。例子如下:
@Transactional
public void testSW() {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int i=10/0;
}
十七:入口方法写上@Transactional 异常出现在被调用方法上或者在入口方法上,且捕获异常。结论:新增和更新都成功。例子如下:
@Transactional
public void testSW() {
try {
primaryReportService.insertBatch(buildInsertPrimary());
primaryReportService.updateBatch(buildUpdatePrimary());
}catch(Exception e) {
System.out.println("捕获异常");
}
}
public void insertBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.insertBatch(primaryReports);
}
public void updateBatch(List<PrimaryReport> primaryReports) {
primaryReportMapper.updateBatch(primaryReports);
int i=10/0;
}