代码中的事务无法回滚

问题来源

有一小伙伴,事务提交是加在方法级上的。并且方法里写了几个更新数据库表的操作。然而当数据前几个顺利执行通过后,发现最后一个操作并未通过。按照一般的事务管理规则,此刻是应该触发事务回滚的。然而并没有触发,前两次操作成功地写入了数据库,最后一次失败告终。

问题追踪

项目大体是使用mysql数据库,管理事务是在spring中完成。其实这里跟开发语言没有任何关系,无论使用什么语言什么框架,都有可能遇到此类问题。分别以下述步骤进行了一番分析:

  1. 查看源码,发现没有逻辑错误

  2. 比对其他方法,业务异常

  3. 到目前为止只能怀疑数据库了

    1. 查看数据库的配置也无什么异常分别是InnoDB以及utf-8编码

    2. 比对操作的表,发现出错的表里使用的引擎(engine)是MyISAM,跟其他表的不一样

结论

mysql一共提供了两种引擎(engine),即InnoDB和MyISAM。查看两种引擎的区别不难发现:

  • InnoDB supports transactions which is not supported by tables which use MyISAM storage engine.

  • InnoDB has row-level locking, relational integrity i.e. supports foreign keys, which is not possible in MyISAM.

  • InnoDB ‘s performance for high volume data cannot be beaten by any other storage engines available.

另外还有一个分析对比,选择合适的引擎:

                                             My ISAM    InnoDB
Required full text Search                      Yes       5.6+
Require Transactions                                     Yes
frequent select queries                        Yes      
frequent insert,update,delete                            Yes
Row Locking (multi processing on single table)           Yes
Relational base design                                   Yes


转载于:https://my.oschina.net/crazyharry/blog/338468

<think>好的,用户现在问的是在Spring Boot中如何实现事务回滚,并列出代码。我需要先回顾之前关于敏捷开发的回答,看看有没有相关的知识点可能关联,但看起来这个问题属于另一个技术领域,所以需要专注解答。 用户可能是在开发过程中遇到了事务管理的问题,需要知道如何在Spring Boot中处理事务回滚。可能的应用场景比如在银行转账操作中,如果一个步骤失败,整个事务需要回滚,保证数据的一致性。 首先,我需要确认Spring Boot中事务管理的基本机制。Spring使用@Transactional注解来声明事务,默认情况下,遇到运行异常(RuntimeException)和错误(Error)回滚。检查型异常(checked exceptions)不会触发回滚,除非特别指定。 接下来,用户需要代码示例,所以需要给出一个典型的Service层方法,加上@Transactional注解。同,可能需要展示如何手动抛出异常以触发回滚,或者如何处理检查型异常的情况。 用户可能对默认的回滚行为不了解,需要解释清楚哪些异常会触发回滚,哪些不会。另外,可能还需要提到如何在注解中指定回滚的异常类型,比如使用rollbackFor属性。 还有,可能需要提到事务的传播行为,比如REQUIRED、REQUIRES_NEW等,但用户的问题主要集中在回滚,所以这部分可能不需要深入,除非用户后续提问。 另外,要注意代码的正确性,确保示例中的异常抛出是正确的,比如使用RuntimeException的子类,或者自定义异常并指定rollbackFor。 可能用户在使用过程中遇到了事务没有回滚的情况,需要检查是否在正确的类和方法上使用了@Transactional注解,或者是否在同一个类内部调用导致代理失效的问题,但这个问题可能稍微复杂,用户的问题可能更基础,先给出基本示例再考虑扩展。 总结回答结构:先介绍@Transactional注解,然后给出代码示例,说明默认行为,如何处理检查型异常,以及手动回滚的方法。最后可能提到一些常见问题和注意事项。</think>### 一、Spring Boot 中事务回滚的核心机制 在 Spring Boot 中,事务回滚通过 **声明式事务管理** 实现,主要依赖 `@Transactional` 注解。其默认行为是: 1. **遇到运行异常(RuntimeException)或错误(Error)自动回滚**。 2. **检查型异常(Checked Exception,如 IOException)默认不触发回滚**,需手动配置。 --- ### 二、基础代码示例 以下是一个典型的 Service 层事务回滚实现: #### 1. 添加依赖(确保 `spring-boot-starter-data-jpa` 或 `spring-boot-starter-jdbc` 存在) ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` #### 2. 启用事务管理(Spring Boot 默认自动配置,无需显式启用) #### 3. Service 层代码 ```java import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class UserService { @Autowired private UserRepository userRepository; @Autowired private AccountRepository accountRepository; // 默认回滚策略:遇到 RuntimeException 或 Error 回滚 @Transactional public void createUserAndAccount(User user, Account account) { userRepository.save(user); // 插入用户 if (account.getBalance() < 0) { // 抛出运行异常,触发回滚 throw new IllegalArgumentException("账户余额不能为负数"); } accountRepository.save(account); // 插入账户 } } ``` --- ### 三、自定义回滚规则 #### 1. 针对检查型异常回滚 通过 `rollbackFor` 属性指定需回滚的异常类型: ```java @Transactional(rollbackFor = IOException.class) public void updateUserWithFile(User user, String filePath) throws IOException { userRepository.save(user); if (!Files.exists(Paths.get(filePath))) { throw new IOException("文件不存在");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值