spring中事务失效场景简介说明
下文笔者讲述Spring中事务失效场景说明,如下所示
spring中事务失效场景
一、权限访问问题 二、方法用final修饰 三、无事务嵌套有事务的方法 四、没有被spring管理 五、设计的表不支持事务 六、没有开启事务 七、错误的事务传播 八、自己捕获了异常 九、手动抛出别的异常 十、自定义回滚异常
spring中事务失效场景
一、权限访问问题
当方法不是public的就事务不生效
二、方法用final修饰
spring事务底层实现使用代理
aop,使用jdk的动态代理或cglib
生成代理类
在代理类中实现了事务功能
当方法被final修饰,无法重写该方法,也就无法添加事务的功能
三、无事务嵌套有事务的方法
public void testPrivate() {
testFinal();
}
@Transactional
public void testFinal(){
TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
.blogUrl("www.java265.com").remark("欢迎访问").build();
userMapper.insertUser(build);
int i = 1 / 0;
}
四、没有被spring管理
对象没有被Spring管理 所以@Transactional注解也没有效果哦
五、设计的表不支持事务
数据库不支持事务 如: MySQL使用MyISAM存储引擎
六、没有开启事务
springboot项目
有自动装配的类DataSourceTransactionManagerAutoConfiguration
已经默认开启事务
配置spring.datasource参数就行
如果是spring项目
需在applicationContext.xml配置
不然事务不会生效
七、错误事务传播
使用@Transactional注解时 可指定propagation参数
spring目前支持7种传播特性
REQUIRED
如果当前上下文中存在事务,那么加入该事务
如果不存在事务,创建一个事务,这是默认的传播属性值
SUPPORTS
如果当前上下文存在事务,则支持事务加入事务
如果不存在事务,则使用非事务的方式执行
MANDATORY
如果当前上下文中存在事务,否则抛出异常
REQUIRES_NEW
每次都会新建一个事务,并且同时将上下文中的事务挂起
执行当前新建事务完成以后,上下文事务恢复再执行
NOT_SUPPORTED
如果当前上下文中存在事务,则挂起当前事务
然后新的方法在没有事务的环境中执行
NEVER
如果当前上下文中存在事务,则抛出异常
否则在无事务环境上执行代码
NESTED
如果当前上下文中存在事务,则嵌套事务执行
如果不存在事务,则新建事务
@Transactional(propagation = Propagation.NEVER)
public void testFinal(){
TbUser build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
.blogUrl("www.java265.com").remark("欢迎访问").build();
userMapper.insertUser(build);
int i = 1 / 0;
}
八、自己捕获了异常
@Transactional
public void testFinal(){
TbUser build = null;
try {
build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
.blogUrl("www.java265.com").remark("欢迎访问").build();
userMapper.insertUser(build);
int i = 1 / 0;
} catch (Exception e) {
System.out.printf(e.toString());
// throw new RuntimeException(e);
}
}
在编写事务时,如果我们使用 try catch 捕获了异常
同时没有手动抛出 异常,则事务不生效(因为不抛出异常,Spring不会捕捉到)
九、手动抛出其他异常
@Transactional
public void testFinal() throws Exception {
TbUser build = null;
try {
build = TbUser.builder().userId(1).userAccount("admin").userPassword("123456")
.blogUrl("www.baidu.com").remark("欢迎访问").build();
userMapper.insertUser(build);
int i = 1 / 0;
} catch (Exception e) {
throw new Exception(e);
// throw new RuntimeException(e);
}
}
//上述手动抛出Exception异常
// Spring事务同样不会回滚
由于spring事务
默认情况下不会回滚Exception(非运行时的异常)
只会回滚RuntimeException(运行时异常)和Error(错误)
十、自定义回滚异常
rollbackFor
默认是RuntimeException 和 Error 及子类抛出,就会回滚
如果 rollbackFor 指定异常类型
则只有指定的异常及子类发生才会回滚
@Transactional(rollbackFor = BusinessException.class)
public void query(Demo demo) throws Exception{
save(demo);
}
BusinessException
是我们自定义异常
当这个异常发生的时候才会回滚
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


