@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。
默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。
个人总结:@Transactional就是将整个方法里面的逻辑全部纳入事务内,除非调用了外部接口也有开启事务的方法,不然作为在同一个事务里面。
下面将以具体的事例来佐证:
@Override
@Transactional
public void test1() {
eventLogService.addEventLog("1", "1", "1");
test2();
test4();
test5();
test();
}
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void test2() {
eventLogService.addEventLog("3", "3", "3");
}
@Override
public void test5() {
eventLogService.addEventLog("3", "3", "3");
}
private void test() {
eventLogService.addEventLog("2", "2", "2");
throw new CouponException("2000", "xiaoxiao");
}
public void test4() {
eventLogService.addEventLog("4", "4", "4");
}
public void addEventLog(String a1, String a2, String a3) {
insert();
}
运行结果显示,test()函数发生了异常,其他函数实际未在数据库中添加数据,从而可以证实上述黑体字的结论,如果有什么纰漏,望请指正