标签:table except name actions stat nbsp str 动态 end
1.@Transactional修饰的方法为非public方法,这个时候@Transactional会实现。
失败的原理是:@Transactional是基于动态代理来实现的,非public的方法,他@Transactional的动态代理对象信息为空,所以不能回滚。
2.在类内部没有添加@Transactional的方法,调用了@Transactional方法时,当你调用是,他也不会回滚
测试代码如下:
@Service public class UserServiceImpl extends implements UserService { @Autowired private UserMapper userMapper; @Override @Transactional public void insertOne() { User user = new User(); user.setUsername("123"); //插入到数据库 userMapper.insert(user); //手动抛出异常 throw new IndexOutOfBoundsException(); } }
失败的原理:@Transactional是基于动态代理对象来实现的,而在类内部的方法的调用是通过this关键字来实现的,没有经过动态代理对象,所以事务回滚失效。
3.就是在@Transactional方法内部捕获了异常,没有在catch代码块里面重新抛出异常,事务也不会回滚。
测试代码如下:
@Override @Transactional public void insertOne() { try { User user = new User(); user.setUsername("123"); //插入到数据库 userMapper.insert(user); //手动抛出异常 throw new IndexOutOfBoundsException(); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } }
解决办法一:加上@Transactional(rollbackFor=Exception.class)
解决办法二: @Transactional的方法里面捕获了异常,手动回滚,
代码如下:
@Override @Transactional public void insertOne() { try { User user = new User(); user.setUsername("123"); //插入到数据库 userMapper.insert(userEntity); //手动抛出异常 throw new IndexOutOfBoundsException(); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }
4.创建表时,引擎是否是InnerDB
mysql数据库常用的引擎有两种(innodb和myisam),在建表时有些dba会默认使用myisam引擎,如果是这种引擎,那么在遇到异常时,数据库是不回滚的。所以将需要回滚的表引擎改为innodb
解决方法:
ALTER TABLE tableName CHANGE TYPE=InnoDB;
标签:table except name actions stat nbsp str 动态 end
原文地址:https://www.cnblogs.com/mylqm/p/14926129.html