项目当中遇到需要使用事务的地方不少。使用过程中事务不生效的方式有哪几种?
测试:这个功能有bug,出错了没回滚!
开发:不可能,这个功能我加了事务!
开发:先默默自测一波
1、首先添加两个方法,saveUser()添加一个名称为张三的用户,cerateUser()创建一个名称为李四的用户(有事务@Transactional注解),事务是否生效?
代码执行结果如下:
数据库此时有两条数据:
说明事务没有生效。抛出异常之后,数据库还是保存了这两条数据。
2、改造一波,给saveUser()方法添加上事务@Transactional注解
调用方法运行一下,查看数据库结果:
数据库中没有数据,说明事务生效,数据进行了回滚,此时你已正确的放对了事务地点了
3、再次改造一下,加一个线程操作,事务此时是否还生效
调用方法运行一下,查看数据库结果:
说明事务不生效,数据没有进行回滚,数据库还是插入了name为张三的数据。说明事务必须要在同一个线程内,否则事务是不生效。
4、改造一下,如果try carch捕获异常之后,事务是否还生效?
调用方法运行一行,此时数据库结果
说明事务不生效,数据没有进行回滚,数据库还是插入了两条的数据。说明事务内不能用try catch进行异常捕获。
5、改造一下,使try catch也能进行事务回滚,手动在catch进行事务回滚操作。
此外还有多种方法,手动抛出异常也可。
6、重新将自己注入,事务也能生效:
还可以选择其它方式让spring代理。这样事务也能生效。
总结:1、saveUser()如果没有添加事务@Transactional,此时调用cerateUser()时,事 务是不生效得。要想事务生效,需要将saveUser()添加@Transactioncl事务
2、不在同一个线程内,事务是不生效得
3、Try catch会让事务不生效,要让其生效,可以手动回滚事务,或者抛出异常
4、Spring的事务是基于aop实现的,aop是基于动态代理实现的,所以事务想要生效,那么必须是被spring动态代理后的类。