添加@Transactional后的方法,不会直接操作数据库,例如保存方法,在执行完保存语句后,数据库并没有出现该数据,只有方法结束之后,才会正式保存到数据库。
从一个方法的调用过程,来分析每个步骤中,有可能导致事务失效的场景。
比如现在bookController调用了一个bookServiceImpl中的insert方法,insert方法添加了@Transactional注解,如果insert方法不是public的,则事务失效;
如果insert方法是public的,insert方法中调用了同类的a方法,如果insert方法没有注解,a方法有注解,则a方法上的注解失效;如果insert调用了不是同类的a方法,如果insert方法么有注解,a方法有注解,则注解不失效。(这个具体可以看我前面的文章)。
如果insert是public的,中间也没有调用别的地方,在方法体中,如果有运行时异常,事务生效;如果不是运行时异常,事务失效。多数情况下,会提示抛出异常,如果try…catch了异常,则事务也失效。
如果insert是public的,注解也加了,方法正常调用了,中间也没有异常捕获,运行时也没有出现异常,正常数据要操作数据库时,如果数据库是mysql且引擎是MyISAM,则事务失效,因为MyISAM不支持事务,可以改成InnoDB。
总结: 1、@Transactional 注解只能应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,事务也会失效。 2、如果调用的方法没加@Transactional,那么被调用的方法家了@Transactional,也不会回滚。 3、异常类型是runtimeException才会回滚的; throw new RuntimeException(“xxxxxxxxxxxx”); 事务回滚 throw new Exception(“xxxxxxxxxxxx”); 事务没有回滚 4、异常被catch住,忘记抛出,事务不会回滚。 5、如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB;
|