前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试专题:简述Spring事务失效原因?

面试专题:简述Spring事务失效原因?

原创
作者头像
小明爱吃火锅
发布2023-12-20 20:12:10
2480
发布2023-12-20 20:12:10
举报
文章被收录于专栏:小明说Java

Spring事务管理是一个非常重要的功能,但在实际操作中,可能会出现事务失效的情况。本文将简要介绍导致Spring事务失效的八大原因,帮助开发者在实际操作中避免这些问题,并且这个问题对于面试中,面试如果要深入面试,经常也会问,事务失效有哪些原因。

1)数据库引擎不支持事务

 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。

2)没有被 Spring 管理 

代码语言:aspnet
复制
// @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

@Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。

3)方法不是 public 的

@Transactional 只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。Spring官网也指出了:

4)自身调用问题

代码语言:applescript
复制
@Service
public class OrderServiceImpl implements OrderService {
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务管用吗?

代码语言:applescript
复制
@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateOrder(Order order) {
        // update order
    }
}

这次在 update 方法上加了 @Transactional,updateOrder 加了 REQUIRES_NEW 新开启一个事务,那么新开的事务管用么?

这两个例子的答案是:不管用!

因为它们发生了自身调用,就调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效,这也是老生常谈的经典问题了。

5) 数据源没有配置事务管理器

代码语言:applescript
复制
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

如上面所示,当前数据源若没有配置事务管理器,那也是白搭

6)设置传播机制为NOT_SUPPORTED不支持事务

Propagation.NOT_SUPPORTED: 表示不以事务运行,当前若存在事务则挂起

7)异常被吃了

代码语言:applescript
复制
 @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
        }
    }
}

异常捕获了,但是又不抛出,导致事务无法回滚

8)异常类型错误

代码语言:applescript
复制
// @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            throw new Exception("更新错误");
        }
    }
}

这样事务也是不生效的,因为默认回滚的是:RuntimeException,如果你想触发其他异常的回滚,需要在注解上配置一下,如

代码语言:apacheconf
复制
@Transactional(rollbackFor = Exception.class)

总结

其实这些事务失效不仅仅说为了应付面试,在实际开发中也是十分有用的,就像我们知道了什么情况会索引失效,进而在开发中就不去避免,事务失效也是,开发尽量避免这些情况,保证事务有效。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1)数据库引擎不支持事务
  • 2)没有被 Spring 管理 
  • 3)方法不是 public 的
  • 4)自身调用问题
  • 5) 数据源没有配置事务管理器
  • 6)设置传播机制为NOT_SUPPORTED不支持事务
  • 7)异常被吃了
  • 8)异常类型错误
  • 总结
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档