Skip to content

MySQL事务

759字约3分钟

数据库mysql事务

2024-10-24

MySQL8 默认数据引擎为InnoDB 支持事务

MySQL5.5之前 默认数据引擎为MyISAM 不支持事务

事务的开始

commit/begin/start transaction;

一个事务的开始意味着上一个事务的结束

使用commit显式提交事务意味着上一个事务的终结和下一个事务的开始

事务保存点

savepoint 保存点名 设置保存点

例:

mysql> savepoint first;
Query OK, 0 rows affected (0.00 sec)

回滚到指定保存点

rollback to 保存点名;

例:

mysql> savepoint second;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into bank values ('测试2',2000);
Query OK, 1 row affected (0.00 sec)

mysql> select * from bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 林冲         |      1000.00 |
| 测试         |      2000.00 |
| 测试2        |      2000.00 |
+--------------+--------------+
3 rows in set (0.00 sec)

mysql> rollback to second;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from bank;
+--------------+--------------+
| customerName | currentMoney |
+--------------+--------------+
| 林冲         |      1000.00 |
| 测试         |      2000.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

DDL语句会导致事务的自动提交

如:create / alter / drop / truncate / table;

事务并发产生的问题

1.脏读

事务A读取到了事务B未提交的数据(脏数据)

级别:uncommitted

解决方法:设置隔离级别为read committed

建立连接后会创建会话,此时会话中已隐式开启了一个事务。

脏数据中已包含了不可重复的问题

2.不可重复读

同一事务中多次查询到的数据不同

(1)事务T1读取某一数据后,事务T2对其做了修改,当事务1再次读该数据时,得到与前一次不同的值。例如,T1读取B=100进行运算,T2读取同一数据B,对其进行修改后将B=200写回数据库。T1为了对读取值校对重读B,B已为200,与第一次读取值不一致。 (2)事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录神密地消失了。 (3)事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入了一些记录,当T1再次按相同条件读取数据时,发现多了一些记录。

级别:committed

原因:

1.读取了另一事务中未提交是数据。(read uncommitted)

2.读取了另一事务中已提交的数据。(read committed)

解决方法:设置隔离级别为repeated read

3.幻读

事务A首先根据条件索引得到N条数据,然后事务B在N条之外删除或者增加了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

与不可重复读中(2)、(3)情况类似

4.丢失更新

两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致了T1的修改失效了。