数据库 为何使用 回滚

你说的这些我都明白,都是我实际做过的坑。

当时还在某公司做项目,对数据库做DDL,比如修改表结构什么的。
如果不这样做,MySQL将继续提示您此操作影响了多少行。
如果最后没有commit,那么操作就会丢失,数据会自动回滚。
这一点是很清楚的。

还有一次,我做了一次批量插入,数据量很大,几万条。
结果中间,对于某些项目,字段类型错误,或者其他什么,直接报错。
你猜怎么着?整个 SQL 被认为是无效的,不会插入任何内容,数据库会自动为您回滚它。
不然你想一想,如果投入了一半,失去了另一半,怎么能说是完整呢?数据必须整洁。

此外,在开发过程中,业务逻辑可能需要同时处理多个表。
比如提款的时候,用户的余额要减少,商户的收入要增加。
如果你夹在中间该怎么办?例如,你设法减少了用户的余额,但未能增加商户的收入?使用业务!在做之前,这整个操作只是一件事。
如果中间出现问题,数据库会帮助你撤销你所做的所有操作。
这称为回滚。
不然数据就乱了,肯定不行。

所以,数据库回滚是为了确保数据操作要么正确,要么全部错误,而不是只正确一半。
简而言之,控制你的数据,不要让它运行。

spring aftercommit中抛异常会怎么样

说白了,如果Spring的afterCommit阶段出现异常,事务不会回滚,但是资源管理不当会导致严重的问题。

首先让我告诉你最重要的事情。
afterCommit 在事务提交后触发。
数据已经写入数据库,因此引发异常是没有用的。
去年我运行那个项目时,在afterCommit中与另一个系统同步失败了一次,并且异常被直接硬编码。
结果,原来的交易数据依然如常,客户抱怨数据不符。
还有3 000级数据同步等其他关键点。
如果直接更新数据库而不打开新事务,那么这些操作将独立执行,并且它们的事务性将会丢失。

一开始我以为在afterCommit中抛出异常就会回滚整个事务,但后来发现我完全错了。
很多人没有注意到这一点。
此外,提交事务后数据库连接可能保持活动状态,但未声明新事务的操作将具有“无事务”状态。
例如,直接运行 SQL 更新可能会导致数据不一致和连接泄漏。

与afterCompletion不同,afterCompletion可以判断事务是否已提交或回滚,而afterCommit则不能。
例如,afterCompletion 要求先释放非事务资源,然后才能处理事务相关的逻辑。

简单来说,afterCommit抛出异常,不回滚,但是需要异步处理、安全的资源释放、良好的日志记录。
说实话,这很令人困惑。
尝试使用消息队列来分离关键任务可能是值得的。