外观
MySQL事务
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的修改失效了。