事务
普通事务
针对数据的持久化,保证数据操作的原子性1,一致性2,隔离性3,持久性4(即 ACID5 原则)。 实现: 日志(Log):通过将所有操作记录到日志中,可以在系统故障后重放日志,实现回滚或重做,保证数据的原子性和一致性。日志先行写入(WAL6)作为一种日志机制,在对数据进行更改前,先将修改写入日志,以便在故障恢复时进行数据还原。 锁机制(Locking Mechanism):利用锁来控制并发事务间的资源访问,确保隔离性。不同的锁模式(如共享锁和排他锁)帮助避免数据冲突。 MVCC7(多版本并发控制, Multi-Version Concurrency Control):通过为数据生成多个版本,允许读写操作并发执行而不冲突。是读已提交与可重复读实现所依赖的一种方式
日志
通过将所有操作记录到日志中,可以在系统故障后重放日志,实现回滚或重做,保证数据的原子性和一致性。日志先行写入(WAL6)作为一种日志机制,在对数据进行更改前,先将修改写入日志,以便在故障恢复时进行数据还原。 二进制日志(Binary Log, binlog) 作用:记录所有对数据库进行的更改(例如增删改操作,但不包括查询)。 用途:用于主从复制(同步数据到从库),以及故障恢复(通过重放日志来恢复到某个时间点)。 错误日志(Error Log) 作用:记录服务器启动、停止过程中的错误和警告信息,以及在运行过程中产生的错误。 用途:便于管理员排查和诊断 MySQL 服务问题。 查询日志(General Query Log) 作用:记录所有的 SQL 查询,包括成功和失败的查询请求。 用途:用于调试,分析所有 SQL 语句的执行情况,但由于记录内容多,通常不建议在生产环境中长期开启。 慢查询日志(Slow Query Log) 作用:记录执行时间超过设定阈值的 SQL 查询。 用途:用于发现和优化性能低下的查询,帮助定位可能需要索引优化或其他性能改进的查询。 中继日志(Relay Log) 作用:在主从复制的从库中使用,记录从主库接收到的二进制日志事件。 用途:用于从库回放主库的更改,以保持主从同步。 事务日志(Transaction Log),也称重做日志(Redo Log) 作用:日志记录事务执行后的状态,确保在系统崩溃后恢复已提交事务。 用途:主要在崩溃恢复场景下使用,帮助实现事务的持久性和一致性。 回滚日志(Undo Log) 作用:用于记录事务开始前的状态。 用途:用于事务失败时的回滚操作;在 MVCC 模式下也用于多版本控制。
锁机制
确保多个事务在访问共享资源时不会发生冲突,从而维护数据的一致性和完整性。锁机制的类型包括: 行锁(Row Locks):允许多个事务同时更新不同的行,适合高并发的场景。 表锁(Table Locks):锁定整个表,适用于需要对表进行整体操作的情况,如修改表结构或执行大批量更新,但会影响并发性能。 共享锁(Shared Locks):允许多个事务同时读取数据,但不允许修改,确保数据的一致性。 排他锁(Exclusive Locks):在事务操作期间禁止其他事务访问被锁定的数据,确保数据的安全性。 意向锁(Intent Locks):用于在更高的层级(如表级别)指示某个事务希望在行级别锁定某些行。
Spring事务的传播性
REQUIRED(默认): 如果当前存在事务,加入当前事务;如果当前没有事务,则创建一个新事务。 通常用于最常见的场景,保证一个方法的执行要么完全成功,要么完全失败。 场景:如果你在一个方法内调用另一个方法,而该方法也需要事务,那么会使用当前的方法事务。 REQUIRES_NEW: 无论当前是否有事务,都会创建一个新的事务。如果当前有事务,当前事务会被挂起,直到新事务完成后再恢复原来的事务。 场景:用于需要独立事务的操作,不能被外部事务回滚。例如,在一个方法中处理重要的操作,但不想让外部事务的失败影响这个操作。 SUPPORTS: 如果当前存在事务,则加入当前事务;如果当前没有事务,则不启动事务。 场景:用于不要求事务的操作,但如果外部有事务,则参与其中。 NOT_SUPPORTED: 如果当前存在事务,则挂起当前事务,并且方法内不支持事务。 场景:用于某些操作不能在事务中进行的情况,比如读取大量数据而不希望受事务的控制。 MANDATORY: 如果当前存在事务,则加入当前事务;如果当前没有事务,则抛出异常。 场景:当方法必须在事务内执行时,外部事务控制下的操作。 NEVER: 如果当前存在事务,则抛出异常;如果当前没有事务,则不启动事务。 场景:用于不能在事务中执行的操作。 NESTED: 如果当前存在事务,则在当前事务内开启一个嵌套事务。如果当前没有事务,则表现为 REQUIRED。 场景:用于当当前事务失败时,嵌套的事务仍然能够回滚,但不影响父事务。
Spring事务失效
https://juejin.cn/post/7179080622504149029
分布式事务
多个独立的系统库在业务中需要保持 ACID 时的解决方案,通常以引入第三方中间件作为协调者,协调多个系统提交或回滚,保证数据的一致性。
实现方案:
两阶段提交(2PC, Two-Phase Commit):
准备阶段:协调者向所有参与者发送准备请求,询问是否可以提交事务。
提交阶段:如果所有参与者都返回“准备好”,协调者则发送提交请求;如果有任何参与者返回“失败”,则发送回滚请求。
三阶段提交(3PC, Three-Phase Commit):
准备阶段:与2PC相同,协调者询问参与者是否可以提交。
预提交阶段:协调者将“预提交”消息发送给所有参与者,参与者将事务状态设置为“预提交”。
提交阶段:如果所有参与者确认预提交,协调者发送提交消息;如果任何参与者失败,协调者发送回滚消息。
基于消息的事务(Message-based Transactions):
通过消息队列(如 Kafka、RabbitMQ)来处理事务,确保消息在处理过程中保持一致性。
TCC(Try-Confirm-Cancel):
尝试阶段(Try):进行资源预留,准备执行。
确认阶段(Confirm):所有服务确认预留成功并提交。
取消阶段(Cancel):如果尝试失败,则进行取消操作。
Saga 模式:
将长事务拆分为多个局部事务,每个局部事务成功后触发下一个局部事务,失败时通过补偿机制撤销之前的事务。
Tips:3PC在2PC的基础上增加了一个“预提交阶段”,这个阶段的主要目的是让参与者能够主动监听协调者的状态,如果协调者下线则回滚事务,避免等待下一步指令导致的资源长时间占用。
优缺点
两阶段提交(2PC): 优点:简单易懂,能够确保所有参与者一致性地提交或回滚事务。开箱即用的第三方工具,代码侵入性低。 缺点:在网络分区或协调者故障时可能导致系统阻塞,且性能较低(需等待所有参与者响应)。 三阶段提交(3PC): 优点:比2PC更具容错能力,能够减少阻塞时间,增加可用性。开箱即用的第三方工具,代码侵入性低。 缺点:实现复杂度高,额外的通信开销也可能影响性能。 补偿事务(Compensating Transactions): 优点:灵活性高,能够适应复杂业务逻辑,减少锁竞争。 缺点:需要额外设计补偿逻辑,可能导致一致性难以保证。 最终一致性(Eventual Consistency): 优点:适合高可用性要求的系统,能够提高系统的响应速度。 缺点:数据在短时间内可能不一致,无法满足严格的ACID要求。 基于消息的事务(Message-based Transactions): 优点:解耦了服务之间的直接依赖,能提升系统的可伸缩性。 缺点:消息传递的顺序和可靠性可能影响一致性,复杂的错误处理需要额外考虑。 TCC(Try-Confirm-Cancel): 优点:可控性强,能够在失败时快速回滚,有利于业务逻辑的拆分。 缺点:实现复杂,需要参与者支持TCC逻辑,且可能引入额外的延迟。 Saga 模式: 优点:通过局部事务降低了对全局一致性的要求,能提高系统的可用性和扩展性。 缺点:需要精心设计补偿操作,事务回滚的顺序可能复杂,处理逻辑繁琐。
问题
1.bin log、undo log、redo log的作用 2.什么是2PC、3PC
- 确保操作的不可分割性。事务中的所有操作要么全部完成,要么完全回滚。即便系统在中途崩溃,操作也不会在“进行中”的状态下被中断,以防止数据出现不完整状态 ↩︎
- 确保事务前后数据的完整性和一致性。无论事务是否成功,数据库都会保持一致的规则约束和逻辑完整性。例如,库存和余额等多个关联数据的业务操作要遵循业务规则,数据不允许出现孤立或不符合业务逻辑的状态 ↩︎
- 保障并发事务互不干扰,防止脏读、幻读和不可重复读等问题。事务的隔离性通过设置隔离级别控制事务间可见性,确保在事务未完成前,外部无法读取其未提交的状态 ↩︎
- 保证在事务成功提交后,数据永久保存,即使系统发生崩溃或故障,事务修改的数据也会保存并可恢复 ↩︎
- ACID 是数据库事务的四大特性,确保操作的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability) ↩︎
- WAL(Write-Ahead Logging,日志先行写入)是一种数据库管理系统中的日志记录机制,用于确保数据的持久性和一致性。其核心思想是在对数据进行实际更改之前,先将这些更改记录到日志中。 ↩︎
- MVCC(多版本并发控制)通过为每个事务提供数据的多个版本(快照),实现高并发的读写操作,同时确保事务的隔离性和一致性,如读已提交和可重复读等隔离级别。 ↩︎
- WAL(Write-Ahead Logging,日志先行写入)是一种数据库管理系统中的日志记录机制,用于确保数据的持久性和一致性。其核心思想是在对数据进行实际更改之前,先将这些更改记录到日志中。 ↩︎