MySQL事务及回滚机制是如何工作的?

21

我刚刚接触到事务管理,想知道:

  1. 使用它的优缺点是什么?
  2. 回滚是如何工作的?旧值是否保存在内存中?如果比较大会发生什么?

对于问题1,我知道在银行转账时必须使用它,但是使用它处理所有事情是否更好呢?


http://dev.mysql.com/doc/refman/5.0/en/commit.html - Rottingham
@Rottingham,是的,我去过那里,但那并不能解释我的问题。;) 而且在谷歌上也没有其他的东西能够解释这些问题,如果你能找到一个解释这些问题的网站,我会很乐意删除这个问题。 - loveNoHate
请注意这些内容的来源。https://dev59.com/C3I95IYBdhLWcg3wyBCc https://dev59.com/-nTYa4cB1Zd3GeqPu3W2 - Rottingham
不想表现得很刻薄,但似乎人们只是一遍又一遍地问已经被回答了无数次的同一个问题,而且我相信我的谷歌和你的谷歌工作方式是一样的。 - Rottingham
抱歉@Rottingham,可能是因为我在问题中描述的搜索词。;) - loveNoHate
1个回答

46

事务的好处在于执行复杂的更改,这可能需要对不同表进行多次更新,并确保它们全部成功或者全部回滚。

这个术语叫做原子性,也就是说,更改不能再被分割成更小的部分。

事实上,MySQL的默认存储引擎InnoDB无论您是否请求,都会对所有事情使用事务。但是大多数人使用一种称为自动提交的模式,在该模式下,每个语句隐式地开始一个事务,并在语句完成后隐式提交。在自动提交模式下,您没有机会选择回滚。要么语句成功,否则如果遇到错误,它会自动回滚。

如果您启动一个显式事务,执行一些更新,然后回滚,InnoDB将恢复数据的原始状态。它通过将其存储在数据库的一个区域中,称为回滚段,来保留原始数据。因此,如果您回滚,它只是重新复制那些数据页面,以替换您更改的页面。

这可能需要一些时间,因此,如果尝试查询已更改但已回滚的数据,则InnoDB会自动绕过并从回滚段中读取原始数据,直到将其合并回表中。

例如,假设您启动一个事务并更新了十亿行。这将复制许多页的原始行到回滚段,然后填充表格以更改数据 - 但更改的数据是未提交的。不能读取未提交的数据,因此查询表的任何人都会自动从回滚段中获取原始数据。

然后回滚您的事务。在接下来的几分钟内,InnoDB逐渐清理,并最终恢复同步。但是,在此期间,任何人都可以继续查询原始数据。

如果您已经提交了事务,则MySQL只会标记所有更改的数据为已提交,随后读取数据的任何人都不会体验从回滚段中读取的轻微开销。


2
酷,回滚段。那是 RAM 还是磁盘/表中的空间? - loveNoHate
2
回滚段位于磁盘上的表空间中。 - Bill Karwin
2
如果我更改了这些十亿行数据,内容超出了回滚段的大小,那么事务会停止吗? - loveNoHate
7
是的,这很罕见,但影响了一些MySQL用户。因此,在MySQL 5.5中,回滚段增加到128个段。在MySQL 5.6中,他们意识到对于大多数用户来说这有点过分了,所以默认值被设置为1个段,但您可以选择分配多达128个段。每个“段”的大小不同,并随需增长,但不能容纳超过1023个事务的更改。 - Bill Karwin
3
CURRENT_TIMESTAMP是NOW()的同义词。手册中指出:“NOW()返回一个常量时间,表示语句开始执行的时间。(在存储函数或触发器中,NOW()返回函数或触发语句开始执行的时间。)这与SYSDATE()的行为不同,后者返回它执行的确切时间。” https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_now - Bill Karwin
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接