MySQL之事务
事务的简介:
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。例如生活中的转账
事务的操作:
方式一:关闭自动提交模式
使用步骤:
- 关闭自动提交模式:
set @@autocommit = 0;
- 执行需要的 SQL 语句,比如插入、更新或删除数据。
- 手动提交事务:
COMMIT;
- 如果有错误或不希望提交更改,可以回滚:
ROLLBACK;
方法二:
另一种通过指令控制事务提交的方式是使用显式事务管理命令,例如使用 START TRANSACTION
或 BEGIN
来开启一个事务。这与设置 autocommit = 0
不同的是,显式事务管理并不会关闭自动提交,而是只对特定事务进行手动控制。操作步骤如下:
通过指令的手动提交方式:
-
开启事务: 使用
START TRANSACTION
或BEGIN
命令来显式地开始一个事务,所有后续的 SQL 操作都在该事务中执行。START TRANSACTION; -- 或者 BEGIN;
-
执行操作: 事务开始后,你可以执行插入、更新、删除等操作:
INSERT INTO table_name (column1, column2) VALUES (value1, value2); UPDATE table_name SET column1 = value WHERE condition;
-
提交事务: 一旦所有操作成功,你可以使用
COMMIT
提交事务,确保所有更改永久生效。COMMIT;
-
回滚事务: 如果操作中出现错误或者你决定不提交更改,可以使用
ROLLBACK
撤销事务中的所有更改:
ROLLBACK;
区别总结:
-
set @@autocommit = 0;
:是关闭自动提交的方式,之后所有的操作都会处于事务中,直到你手动提交或回滚。适用于需要长时间控制事务的场景。 -
显式事务控制(
START TRANSACTION
或BEGIN
):开启事务的显式方式,这种方式不影响autocommit
的全局设置,仅控制当前事务的提交与回滚。这种方式灵活性更高,适用于局部的事务控制。
事务的四大特性简称为ACID特性:
-
原子性(Atomicity):事务中的所有操作是一个整体,要么全部执行成功,要么全部执行失败。如果其中任何一个操作失败,整个事务将会回滚到初始状态。
-
一致性(Consistency):事务执行前后,数据库保持一致的状态。无论事务成功与否,数据库的完整性约束不能被破坏。
-
隔离性(Isolation):并发执行的事务相互隔离,互不影响。一个事务的中间状态对其他事务是不可见的。
-
持久性(Durability):一旦事务提交,所做的修改会永久保存,即使系统发生故障,事务的结果也会持久存在。
并发事务问题:
- 脏读:
- 描述:一个事务读取了另一个事务还没有提交的数据。如果后续事务回滚,那么读取到的数据可能是无效的,导致脏读。
- 不可重复读:
- 描述:一个事务先后读取同一条记录,但两次读取的数据不同,这种情况称为不可重复读。通常是因为另一个事务修改了该记录并提交,导致两次读取结果不一致。
- 幻读:
- 描述:一个事务按条件查询数据时,发现符合条件的数据不存在,但在插入数据时发现这些数据已经存在,仿佛这些数据“出现了幻影”。幻读通常是由于另一个事务插入了新数据导致的。
事务的隔离级别:
读未提交(Read Uncommitted) | 可能 | 可能 | 可能 |
读已提交(Read Committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable Read(默认) | 不可能 | 不可能 | 可能 |
串行化(Serializable) | 不可能 | 不可能 | 不可能 |
选择事务隔离级别的考虑因素:
- 性能:隔离级别越高,性能开销越大,因为更高的隔离级别需要更多的锁定和等待。
- 数据一致性需求:如果应用程序对数据一致性要求较高,可以选择更高的隔离级别;否则可以选择较低的隔离级别来提高并发性。
1. 查询当前事务隔离级别
要查询当前会话或全局的事务隔离级别,可以使用以下 SQL 命令:
查询当前会话的事务隔离级别:
SELECT @@tx_isolation;
-- 或者在 MySQL 8.0 及以上版本:
SELECT @@transaction_isolation;
2. 设置事务隔离级别
可以在全局或会话范围内设置事务的隔离级别。常见的隔离级别包括:
- READ UNCOMMITTED(读未提交)
- READ COMMITTED(读已提交)
- REPEATABLE READ(可重复读)
- SERIALIZABLE(串行化)
设置当前会话的事务隔离级别:
要仅为当前会话设置事务隔离级别,可以使用以下命令:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
set session transaction isolation level serializable ;
3. 在事务中动态设置隔离级别
如果想在事务开始前设置隔离级别,你可以在执行 START TRANSACTION
或 BEGIN
之前指定隔离级别:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
-- 执行事务相关的操作
COMMIT;