声明式的事务管理是基于AOP的,在springboot中可以通过@Transactional注解的方式获得支持,这种方式的优点是:
1)非侵入式,业务逻辑不受事务管理代码的污染。
2)方法级别的事务回滚,合理划分方法的粒度可以做到符合各种业务场景的事务管理。
在设计service层的时候,在需要开启事务的方法用@Transactional注解,默认的话在抛出Exception.class异常的时候,就会触发方法中所有数据库操作回滚,当然这指的是增、删、改。
你要在Application类中开启事务管理,开启事务管理很简单,只需要@EnableTransactionManagement注解就行,就像这样:
@SpringBootApplication
@MapperScan(basePackages = "com.blacktv.springboot.database.mapper")//将指定包内自动注册为mapper接口
@EnableTransactionManagement()//开启声明式事务
public class SpringbootHelloApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootHelloApplication.class, args);
}
}
注意开启事务要保证你的数据库引擎是InnoDB的。
案例:
StundetService,这里只放出了有事务的方法:
/**
* Student类的业务逻辑类
*/
@Service
public class StudentService {
@Autowired
private StudentMapper studentMapper;//在启动入口类用@MapperScan注解扫描mapper接口,idea可能会在这里报错,不用担心只是误报
/**
* 添加两个学生,测试事务。
* 事务5秒后超时,发生ArithmeticException和IOException异常时回滚事务
*
* @return
*/
@Transactional(timeout = 5, rollbackFor = {ArithmeticException.class, IOException.class})
public void addDouble(Student student1, Student student2) {
studentMapper.add(student1);
System.out.println(1 / 0);
studentMapper.add(student2);
}
}
@RestController
public class TestA {
@Autowired
private StudentService studentService;
/**
* 测试一下事务
* @param name1
* @param name2
* @return
*/
@GetMapping(value = "/addDouble")
public String addDouble(String name1,String name2){
studentService.addDouble(new Student(name1), new Student(name2));
return "test page";
}
}
先调用一下添加两个学生的接口
通过查询方法查询一下,验证是否回滚了事务,可见是回滚了