1.事务
构成单一逻辑工作单元的操作集合称作事物(transaction),他是作为不可分割的逻辑单元执行的一组SQL语句。
MySQL8默认的引擎是InnoDB,该引擎是支持事务的。
早期的MySQL(mysql5.5之前)默认的引擎是MyISAM。他是不支持事务的。
举例:
设存在 t_accounts 表,其中存在两个账户
id card_no(账户) name balance(余额) 1 1234 张某 20000 2 5678 李某 10000 张某向李某转账5000元。
a、开启事物务(begin)
b、张某账户上减少5000
UPDATE t_accounts SET balance = balance - 5000 WHERE card_no = '1234';
c、李某账户上增加5000
UPDATE t_accounts SET balance = balance + 5000 WHERE card_no = '5678';
d、提交事务 (commit)
2.事务特性(ACID)
a、Atomicity(原子性):
事务中所有的操作要么都发生,要么都不发生,不可能存在一些操作成功,一些操作失败。
举例(张某向李某转账5000元):
-- 张某账户上减少5000 UPDATE t_accounts SET balance = balance - 5000 WHERE card_no = '1234'; -- 李某账户上增加5000 UPDATE t_accounts SET balance = balance + 5000 WHERE card_no = '5678'; -- 不能存在张某成功转帐了,钱减少了,李某没有收到转账,钱没有增加 -- 或者 -- 张某没有转账,钱没变,李某收到转账,钱增加了。
b、Consistency(一致性)
事务将数据库从一种一致状态转变为另一种一致状态。
举例(张某向李某转账):
数据库从
id card_no(账户) name balance(余额) 1 1234 张某 20000 2 5678 李某 10000 转变为
id card_no(账户) name balance(余额) 1 1234 张某 15000 2 5678 李某 15000
c、Isolation(隔离性)
一个事务的执行,不应该收到其他事务的影响。事务与事务之间是独立的。
d、Durability(持久性)
事务一旦提交,其结果就是持久的。
3.事务的提交模式
a、查询当前会话中事务的提交模式
SELECT @@autocommit FROM dual ;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
-- FROM dual 可以省略。dual是个虚表。
-- 如果系统变量@@autocommit 取值为1.则表示当前会话中的事务提交模式为自动提交。
-- 取值为0就是手动提交
b、关闭自动提交
SET @@autocommit = 0 ;
-- set是MySQL提供的一个指令,可以修改一个变量的值,也可以设置一个变量。
c、如果我们希望自主控制事务的 提交 与 回滚(ROLLBACK) , 需要先关闭自动提交,才能自主控制。
d、一旦一个事务提交(commit),就代表另一个事务已经开启,即使在后面回滚,也只能回滚到commit之后新开启的这个事务。
退出mysql提示符就意味着结束事务、终止会话、断开连接。
如果重新链接MySQL意味着建立新的连接、开启新的会话、开启新的事务。
通过查询系统变量 @@autocommit 可以证明本次会话与上次连接时所设置事务提交方式的无关。
不是一个连接对应一个会话,连接和会话也不是一对一的关系。
4.事务的隔离级别
a.查看当前事务的隔离级别
SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
-- 曾经的@@tx_isolation在MySQL 8中已经不再适用
b.事务的隔离级别(SQL92版本中)
-
READ UNCOMMITTED 读未提交
-
READ COMMITTED 读已提交
-
REPEATABLE READ 可重复读
-
SERIALIZABLE 串行化
c.改变事务的隔离级别
-- 方法(标准写法)
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [隔离种类]
-- 举例
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED ;
-- 查询是否更改成功
SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-COMMITTED |
+-------------------------+
d.MYSQL现在的版本默认隔离级别是可重复读,不可重复读是能够避免脏读的。修改MySQL当前会话隔离级别为未提交读,未提交读的隔离级别是可能产生脏读的。
5.事务控制语句
COMMIT与ROLLBACK是互斥的,不可能同时实现。
-
开始事务 BEGIN(mysql)
-- 在一个会话中开启一个新事务的语句 -- 方法一: begin; -- 方法二: start transaction;
-
提交事务 COMMIT
-- 一旦commit,就改不了了。 -- 使用commit显示提交事务意味着上一个事务终结,下一个事务开始。
-
回滚事务 ROLLBACK
-- 回滚事务使用rollback 或者 rollback to语句 -- 把这个事务里面的所有操作全部撤销了。
-
注意
1.在未显示提交事务的前提下,又显示开启了事务。则上一个事务就自动commit了。
6.事务保存点
-
SAVEPOINT identifier 设置保存点
-- identifier代表标识符,在一个事务中,绝对不可以重复 -- 设置保存点 SAVEPOINT first; -- 设置保存点 SAVEPOINT second;
-
RELEASE SAVEPOINT identifier 释放保存点
-- 把某个保存点删除掉
-
ROLLBACK TO identifier 回滚到保存点
-- 回滚到指定的保持点 ROLLBACK TO third ; -- 回滚到一个保存点后,这个保存点之后的保存点将自动失效。 -- 如果设置了多个保存点,想直接回到原始数据,就直接使用ROLLBACK。当然,设置的所有的保存点讲全部失效。
7.事务并发产生的问题
-
Dirty Read 脏读
-
Lost Update 丢失更新1
-
Lost Update 丢失更新2
-
Nonrepeatable Read 不可重复读
-
Phantom Read 幻读