什么是事务
//在默认情况下,数据库的事物作用范围是在JpaRepository的CRUD方法上,
//save方法一旦执行成功马上提交
//要保证数据的完整性,那就需要将事务提高至imp方法上
怎样开启事务
Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。
//在imp方法上开启事务,是需要增加@Transactional
//针对于这种使用注解的事务形式,也有一个名词叫做"声明式事务" , ParseException
示例:
@Transactional(rollbackFor = Exception.class)//开启事务,imp方法运行成功提交。运行失败抛出RuntimeException及其子类的时候回滚
public void imp(){
for(int i = 0 ; i< 10 ; i++){
Emp emp = new Emp();
if(i == 3){
throw new RuntimeException("我出错啦");
}
emp.setComm(0f);
emp.setEname("laoqi" + i);
emp.setHiredate(new Date());
emp.setJob("Teacher");
emp.setMgr(null);
emp.setSal(i*10f);
Dept d = deptRepository.findById(20).get();
emp.setDept(d);
//saveAndFlush立即执行
empRepository.saveAndFlush(emp);
}
@Transactional()参数说明
- @Transactional 不写参数的情况下,开启事务,imp方法运行成功提交。运行失败抛出RuntimeException及其子类的时候回滚
- @Transactional(rollbackFor = Exception.class)将回滚异常的级别提高的Exception级别,一般用该参数,比较稳妥,避免framework级别异常导致的回滚失败
- @Transactional(propagation = Propagation.NOT_SUPPORTED , readOnly = true)//不开启事务的方法
其他说明
@Transactional为org.framework.transactional,而不是javax.transactional
一般情况下,事务注解要写在最核心的Service上,而不是Controller
可以在类的级别上,说明事务,说明该类下的所有方法都开启事务
示例:@Transactional(rollbackFor = Exception.class)
public class EmpController {
@Autowired
private EmpRepository empRepository;
@Autowired
private DeptRepository deptRepository;
@GetMapping("/{id}")
public Emp findById(@PathVariable(“id”) Integer id){
return empRepository.findById(id).get();
}
@GetMapping("/create")
public Emp create(){
Emp emp = new Emp();
emp.setComm(0f);
emp.setEname(“laoqi”);
emp.setHiredate(new Date());
emp.setJob(“Teacher”);
emp.setMgr(null);
emp.setSal(0f);
Dept d = deptRepository.findById(20).get();
emp.setDept(d);
empRepository.save(emp);
return emp;
}@GetMapping("/find") @Transactional(propagation = Propagation.NOT_SUPPORTED , readOnly = true)//不开启事务的方法 public List<Emp> find(Integer deptno){ return empRepository.findEmps(deptno); } @GetMapping("/imp") //在默认情况下,数据库的事物作用范围是在JpaRepository的CRUD方法上, //save方法一旦执行成功马上提交 //要保证数据的完整性,那就需要将事务提高至imp方法上 //在imp方法上开启事务,是需要增加@Transactional //针对于这种使用注解的事务形式,也有一个名词叫做"声明式事务" , ParseException //一般情况下,事务注解要写在最核心的Service上,而不是Controller @Transactional(rollbackFor = Exception.class)//开启事务,imp方法运行成功提交。运行失败抛出RuntimeException及其子类的时候回滚 public void imp(){ for(int i = 0 ; i< 10 ; i++){ Emp emp = new Emp(); if(i == 3){ throw new RuntimeException("我出错啦"); } emp.setComm(0f); emp.setEname("laoqi" + i); emp.setHiredate(new Date()); emp.setJob("Teacher"); emp.setMgr(null); emp.setSal(i*10f); Dept d = deptRepository.findById(20).get(); emp.setDept(d); //saveAndFlush立即执行 empRepository.saveAndFlush(emp); } }
}
在类上声明事务后,又在类中的方法上声明了事务,最后生效的以最近的事务声明为准,即在方法上的事务声明会生效。