> For the complete documentation index, see [llms.txt](https://chesterzhang666.gitbook.io/intro-mysql/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chesterzhang666.gitbook.io/intro-mysql/transaction.md).

# Transaction

MySQL 事务机制，手动管理事务机制，手动管理事务机制的隔离性

## 什么是 MySQL 事务机制 ?

用一句话说，**事务机制就是 要么不做，要么做完的机制，MySQL 就支持这种机制**

**MySQL的事务机制运行如下图所示:**

![](https://3865111145-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Mf8HEXAkAiqRjkH5dlc%2F-MfcRdDJU5J8VFwnDzm1%2F-MfcRfS4pRE6t_ybTLFB%2Ftransaction.png?alt=media\&token=1a852d4b-2aab-4ec7-8352-ae08b31a2b72)

SQL 语句并不是直接对数据库进行操作, 而是将数据库里的数据先复制到 undo 日志当中， 在undo日志里面进行修改。随后若确定保存更改，则将undo日志里面的修改记录提交到redo日志当中，交由redo日志对数据库进行数据操作。若不确定不修改数据，则undo日志将原来的数据返回到数据库当中。

## 为什么要事务机制?

假设这么一个场景, 有多条SQL语句需要执行，执行到一半的时候，机房停电。随后恢复供电，问题来了？我们此时并不知道执行到了第几条SQL语句, 不知道数据库里面哪些数据被修改了，这是非常严重的后果。

事务机制就能规避这种风险，我们先把需要修改的记录保存到redo日志中，交由redo日志去处理，假设在提交过程停电也没有关系，因为所有的修改记录已经在redo日志中了，redo日志重新对数据进行同步即可。

## 手动开启MySQL事务机制

默认情况下，MySQL 对每一句SQL 语句都使用了事务机制。但实际情况中，我们需要确保一次性执行完成多条SQL语句。这时候就需要手动管理事务机制了。

MySQL 手动管理事务机制非常简单, 只需要把SQL语句包裹在 START TRANSACTION - COMMIT (表示提交修改) 或者 START TRANSACTION - ROLLBACK (表示数据回滚) 即可。

```sql
START TRANSACTION
# SQL 语句
COMMIT;

START TRANSACTION
# SQL 语句
ROLLBACK;

```

## 事务机制的四个特性

1. 原子性，要么做完，要么不做
2. 一致性，不管有多么的高并发，执行结果一定正确
3. 隔离性，事务不受其他事务的影响
4. 持久性，事务一旦提交，结果就不可改变，即使遇到死机，停电，也可以通过日志完成对数据的修改

## 手动管理事务隔离级别

事务有四种隔离级别，分别是

1. READ UNCOMMITED, 可以读取未提交的数据
2. READ COMMITED, 可以读取已提交的数据
3. REPEATABLE READ, 可以重复读取数据
4. SERIALIZABLE, 序列化执行事务，也就是事务一个一个执行，不支持并发

在SQL 中设置事务隔离级别也非常简单，只需要在 手动开启事务之前运行一句SQL语句即可。随后整个会话(也就是在当前SQL文件中)，事务的隔离级别都是如此。

```sql
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

START TRANSACTION
#	SQL 语句
COMMIT; #或者 ROLLBACK
```
