问题描述:
在同一个方法中,执行 1:创建新表; 2:增加创建新表信息;当增加新表信息成功、创建新表失败后,数据不能回滚。
思考原因:
1.是不是事务没有配好?
2.创建新表是不是不支持事务?
问题原因:
1.mysql 创建/删除表或更改表结构立即生效,不会回滚。
解决办法:
使用try{}catch{}的方式将上面的动作“包”起来,一旦出现了异常,就catch捕获,然后在catch中删除表,删除数据等操作,“模拟回滚”的效果。
延伸
问题1:事务不生效的几种情况?
1.1 mysql中修改表结构(创建表、删除表、插入表字段),会自动提交事务;
1.2 内部调用: 同一个类中,不带事务的方法A调用带事务的方法B,带事务的方法B遇到异常不会回滚。
解析原因:JDK的动态代理。只有被动态代理直接调用时才会产生事务。在SpringIoC容器中返回的调用的对象是代理对象而不是真实的对象。因为spring的回滚是用过代理模式生成的,如果是一个不带事务的方法调用该类的带事务的方法,直接通过this.xxx()调用,而不生成代理事务,所以事务不起作用。
常见解决方法:
1.拆类:方法A上可以不开启事务,方法B上开启事务,并在方法A中将this调用改成动态代理调用
2.在方法A上开启事务,方法B不用事务或默认事务;
1.3 使用默认的事务处理方式: Spring管理事务默认回滚异常为RuntimeException或者Error,所以当遇到IOException异常等其他异常时,不会触发事务回滚。
常见解决方法:
常用1.添加rollbackfor=Exception.class来表示所有的Exception都回滚。
1.4 数据库表类型错误: 使用InnoDB类型的表才支持事务,使用MyISAM表类型是不支持事务的。
解决方法:更改表的类型:alert table xx type=InnoDB;
1.5 所代理的方法是私有的
1.6 spring配置的扫描包错误
网友评论