异常代码
下面代码为了测试统一写在方法上
@GetMapping("testOne")
@Transactional()
public PTreeFolder testOne() {
PTreeFolder insertData1=new PTreeFolder();
String guid1=java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1= this.pTreeFolderService.insert(insertData1);
PTreeFolder pData =this.pTreeFolderService.queryById(guid1);
PTreeFolder insertData2=new PTreeFolder();
String guid2=java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2= this.pTreeFolderService.insert(insertData2);
return p2;
}
断点调试
进异常
结果分析:
p1是正常数据,p2缺少主键,执行以后走了异常,数据pData是查询的值,注意异常之前是可以查询到的,这个时候数据库是不存储数据的(包括p1)。
执行完成以后报500,数据库存储了0条记录。
结果就是看到数据回滚了。
Catch如何处理
@GetMapping("testOne")
@Transactional()
public PTreeFolder testOne() {
try {
PTreeFolder insertData1=new PTreeFolder();
String guid1=java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1= this.pTreeFolderService.insert(insertData1);
PTreeFolder pData =this.pTreeFolderService.queryById(guid1);
PTreeFolder insertData2=new PTreeFolder();
String guid2=java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2= this.pTreeFolderService.insert(insertData2);
return p2;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
执行以后
也就是说不会回滚。
分析
触发Transactional的回滚 需要RunTimeException异常。
如果要在抛出 非RuntimeException时也触发回滚机制,需要我们在注解上添加 rollbackFor = { Exception.class }属性。
@Transactional(rollbackFor = { Exception.class })
Try catch 以后异常被catch捕获不会触发Transactional的回滚。
解决
1、@ Transactional +catch中抛出RuntimeException异常
@GetMapping("testOne")
@Transactional()
public PTreeFolder testOne() {
try {
PTreeFolder insertData1=new PTreeFolder();
String guid1=java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1= this.pTreeFolderService.insert(insertData1);
PTreeFolder pData =this.pTreeFolderService.queryById(guid1);
PTreeFolder insertData2=new PTreeFolder();
String guid2=java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2= this.pTreeFolderService.insert(insertData2);
return p2;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
2、@Transactional(rollbackFor = { Exception.class }) 加上 catch中throw e
@GetMapping("testOne")
@Transactional(rollbackFor = { Exception.class })
public PTreeFolder testOne() {
try {
PTreeFolder insertData1=new PTreeFolder();
String guid1=java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1= this.pTreeFolderService.insert(insertData1);
PTreeFolder pData =this.pTreeFolderService.queryById(guid1);
PTreeFolder insertData2=new PTreeFolder();
String guid2=java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2= this.pTreeFolderService.insert(insertData2);
return p2;
} catch (Exception e) {
e.printStackTrace();
throw e;
} }
3、直接回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
代码
@GetMapping("testOne")
@Transactional()
public PTreeFolder testOne() {
try {
PTreeFolder insertData1 = new PTreeFolder();
String guid1 = java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1 = this.pTreeFolderService.insert(insertData1);
PTreeFolder pData = this.pTreeFolderService.queryById(guid1);
PTreeFolder insertData2 = new PTreeFolder();
String guid2 = java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2 = this.pTreeFolderService.insert(insertData2);
return p2;
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
PTreeFolder resultData3 = new PTreeFolder();
resultData3.setName("ddd");
return resultData3;
}
}
推荐写法
@GetMapping("testOne")
public PTreeFolder testOne() {
return this.pTreeFolderService.updateTest();
}
在Service中添加方法
@Transactional()
@Override
public PTreeFolder updateTest(){
try {
PTreeFolder insertData1 = new PTreeFolder();
String guid1 = java.util.UUID.randomUUID().toString();
insertData1.setFolderId(guid1);
insertData1.setName("12");
PTreeFolder p1 = insert(insertData1);
PTreeFolder pData = queryById(guid1);
PTreeFolder insertData2 = new PTreeFolder();
String guid2 = java.util.UUID.randomUUID().toString();
//insertData2.setFolderId(guid2);
insertData2.setName("12");
PTreeFolder p2 = insert(insertData2);
return p2;
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
PTreeFolder resultData3 = new PTreeFolder();
resultData3.setName("ddd");
return resultData3;
}
}