Mysql数据库的事务

1.事务的含义:

事务可以简单理解为一组操作,这些操作要么一起成功执行,要么都不执行。就像一个完整的任务,如果这个任务的一部分失败了,整个任务都要放弃。这样做的目的是为了确保数据的一致性和完整性。

2.Mysql事务的特性:

原子性:事务中所有的操作要么一起成功,要么全一起失败。

一致性:事务在执行前后 ,数据库的数据要跟结果始终保持一致。

隔离性:一个事务请求统一数据,多个事务同时进行时,互不影响。

持久性:一旦事务成功提交,其结果是永久生效的,不会因为系统故障而丢失。

事务就像一个整体的工作任务,确保每一步都正确完成,才能算这个任务成功,避免中途出错导致的问题

3.事务的并发问题:

1. 脏读(Dirty Read)

定义:脏读是指一个事务读取了另一个事务未提交的修改。在这种情况下,如果被读取的事务回滚,那么读取到的数据就是不一致的。

示例:

事务A更新了一条记录,将price从100改为200,但事务A尚未提交。

同时,事务B读取了这条记录的数据,此时事务B看到的price是200。

如果事务A之后回滚,那么事务B读取的200就是一个脏读,因为这条记录最终并不存在。

2. 不可重复读(Non-repeatable Read)

定义:不可重复读是指在同一事务中,读取同一数据记录的两次结果不相同。换句话说,如果一个事务在读取某个数据后,另一个事务对该数据进行了更新或删除,那么当第一个事务再次读取该数据时,结果会不同。

示例:

事务A执行时读取了用户的balance,假设是100。

随后,事务B对该用户的balance进行了更新,将其改为150并提交。

当事务A再次尝试读取该用户的balance时,看到的值是150,而不是之前的100。这种情况就是不可重复读。

3. 幻读(Phantom Read)

定义:幻读是指在一个事务中,读取了一组数据的结果(例如SQL查询),在同一事务中再次读取时,结果集发生了变化(例如记录的数量变化),通常是因为其他事务进行了插入或删除操作。

示例:

事务A执行以下查询,返回了某个条件下的所有用户,假设有3个用户。

SELECT * FROM users WHERE age > 18;

事务B随后插入了一个新用户,满足上述查询条件,提交后。

当事务A再次执行相同的查询时,发现返回了4个用户,而不是之前的3个用户。这个新增的用户视为“幻影”,因为它在第一次查询时并不存在。

4. 事务的并发场景

1.读一读 :不存在任何问题

解释:

在两个事务都只是执行读操作的情况下(例如,事务 A 和事务 B 都只执行 SELECT 查询),不会存在任何问题。这是因为读取操作不会修改数据,因此无论是不同事务还是同一个事务多次读取,结果都是一致的。在这种情况下:

没有脏读:因为没有事务在输出未提交的数据。
没有不可重复读:因为没有写入数据。
没有幻读:因为没有插入新的数据行。

2.读一写 :有线程安全问题,脏读,幻读,不可重复读

解释:

在一个事务进行读操作时,另一个事务进行写操作时,可能会出现多种线程安全问题的相关性,尤其是脏读、不可重复读和幻读:

脏读(Dirty Read):事务 A 读取了事务 B 的未提交数据,如果事务 B 之后回滚,那么事务 A 就读取了一个无效的数据状态。

不可重复读(Non-repeatable Read):事务 A 在读取某行数据后,事务 B 对该行数据进行了更新。如果事务 A 再次读取同一行数据,可能会得到不同的结果。

幻读(Phantom Read):事务 A 在进行某个条件的查询时(如某个范围内的行),事务 B 在此期间插入了一行新数据。此时,事务 A 再次执行相同的查询,可能会得到新的记录,造成原有结果集的“幻觉”。

3.写一写 : 有线程安全问题,可能存在数据丢失

解释:

当两个事务都尝试对同一数据进行写操作时,会出现更严重的线程安全问题,导致数据不一致,甚至数据丢失的情况:

数据丢失:如果两个事务同时修改同一行数据,而都以某种方式完成(例如,一个事务的改变覆盖了另一个事务),这可能导致一个事务的结果被另一个事务覆盖,从而导致数据丢失。例如,事务 A 更新了某个字段,事务 B 也更新了同一个字段,最终结果可能只保留事务 B 的更改。

写冲突:由于两个写事务争夺对数据的控制,可能会导致事务提交失败或回滚的情况。

5.事务的隔离级别

读未提交 :允许一个事务读取另一个事务未提交的数据。这是最低的隔离级别,可能会导致“脏读”问题。

读已提交:一个事务只能读取已提交的事务所做的修改。这样可以防止“脏读”现象。

可重复读:在一个事务中,如果读取了某个数据,在事务结束之前再次读取该数据得到的结果不会改变。可以防止“脏读”和“不可重复读”现象,但仍然可能出现“幻读”。

串行化 :这是最高的隔离级别,强制所有事务完全串行执行。任何事务都无法开始,直到其他事务完成。这可以防止“脏读”、“不可重复读”和“幻读”现象。

6.事务的实现原理

MySQL 支持多个存储引擎,每个存储引擎具有不同的事务处理机制。最常用的存储引擎是 InnoDB,它为事务提供了全面的支持。

6.1 锁机制
  • 行级锁:InnoDB 使用行级锁来提高并发性,只锁定被事务修改的行,而不是整个表。
  • 表级锁:MyISAM 存储引擎使用表级锁,会锁定整个表,导致并发性较差。
  • 多版本并发控制(MVCC):InnoDB 使用 MVCC 来实现高效的事务隔离。每个事务都有一个快照,可以在非锁定的情况下读取数据,避免了读锁和写锁的冲突。
6.2 日志管理

MySQL 使用两种日志来管理事务:

  • 重做日志(Redo Log):记录已提交事务的所有改变,这是为了保证持久性。即使系统崩溃,重启后可以通过重做日志恢复到最新状态。
  • 回滚日志(Undo Log):用来支持事务的回滚和实现原子性。当事务被回滚时,通过回滚日志来撤销已经执行的操作。

6.3 事务的操作

在 MySQL 中,常用的事务操作有:

  • BEGIN / START TRANSACTION:开始一个新的事务。
  • COMMIT:提交事务,生效所有在事务中的更改。
  • ROLLBACK:回滚事务,撤销在事务期间所做的所有更改。

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL数据库事务是一组数据库操作命令的集合,这些命令要么全部执行成功,要么全部回滚。事务具有以下特性: 1. 原子性(Atomicity):事务中的所有操作要么全部成功执行,要么全部回滚,不会出现部分执行的情况。 2. 一致性(Consistency):事务执行前后,数据库的状态保持一致,即满足预设的约束条件。 3. 隔离性(Isolation):并发执行的事务之间相互隔离,每个事务都感觉不到其他事务的存在。 4. 持久性(Durability):事务一旦提交,其结果将永久保存在数据库中,即使系统发生故障也不会丢失。 在MySQL中,可以使用以下语句来控制事务的开始、提交和回滚: 1. 开始事务:`START TRANSACTION;` 或 `BEGIN;` 2. 提交事务:`COMMIT;` 3. 回滚事务:`ROLLBACK;` 以下是一个示例,演示了如何在MySQL中使用事务: ```sql -- 开始事务 START TRANSACTION; -- 执行一系列数据库操作命令 INSERT INTO table1 (column1, column2) VALUES ('value1', 'value2'); UPDATE table2 SET column1 = 'new_value' WHERE condition; DELETE FROM table3 WHERE condition; -- 提交事务 COMMIT; ``` 如果在事务执行过程中发生了错误,可以使用回滚操作将事务恢复到开始之前的状态: ```sql -- 开始事务 START TRANSACTION; -- 执行一系列数据库操作命令 INSERT INTO table1 (column1, column2) VALUES ('value1', 'value2'); UPDATE table2 SET column1 = 'new_value' WHERE condition; DELETE FROM table3 WHERE condition; -- 发生错误,回滚事务 ROLLBACK; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值