事务篇
一、数据库事务概述
(1)概念
事务
是一组逻辑操作单元,使数据从一种状态变换到另一种状态
(2)事务的处理原则
- 在一个事务中,
要么所有的操作都成功执行并最终提交
,要么如果其中任何一个操作失败,整个事务会被回滚
,保证数据库状态不会受到部分操作的影响。- 事务特别适合用于需要保持数据一致性的场景,如:
银行转账
等需要同时更新多个表的操作。
(3)事务的特性(ACID)
原子性 Atomicity:
一个事务不可再分割,要么 都执行 要么 都不执行一致性 Consistency:
一个事务执行会使数据从一个 一致状态 切换到 另外一个一致状态隔离性 Isolation:
一个事务的执行 不受 其他事务的 干扰持久性 Durability:
一个事务一旦提交,则会 永久的改变 数据库的数据.`
(4)事务的创建
1、隐式事务
- 事务
没有明显
的开启
和结束
的标记
,比如insert
、update
、delete
语句
关键字:autocommit
关闭:set autocommit = false;
- 默认是
开启
的,如下图可以通过命令查看;
开启之后,每一条增改操作都是一个独立的事务
2、显式事务
- 事务
具有明显
的开启
和结束
的标记
前提: 必须 先设置自动提交功能为禁用
:set autocommit=0;
步骤1:
开启
事务
set autocommit=0;
start transaction;
------------------可选的步骤2:
编写
事务中的sql语句
(select insert update delete
)
语句1;
...
步骤3:
结束
事务
commit;
---------------------提交事务
或
rollback;
------------------回滚事务
二、如何使用事务
1. 确认使用支持事务的存储引擎
MySQL
中只有InnoDB
等存储引擎支持事务,而MyISAM
等不支持。因此,首先确保您的表使用的是InnoDB
引擎。
-- 检查表的存储引擎
SHOW TABLE STATUS WHERE Name = 'your_table_name';
-- 如果需要,修改表的存储引擎为InnoDB
ALTER TABLE your_table_name ENGINE=InnoDB;
2. 开始事务
- 使用
START TRANSACTION、BEGIN
或者BEGIN
命令开始一个事务。
START TRANSACTION;
-- 或者
BEGIN;
3. 执行数据库操作
- 在事务块中执行您的
SQL
语句,如INSERT、UPDATE、DELETE
等。
INSERT INTO your_table (column1, column2) VALUES (value1, value2);
UPDATE your_table SET column1 = value WHERE condition;
DELETE FROM your_table WHERE condition;
4. 提交或回滚事务
- 提交事务:如果所有操作都成功,使用
COMMIT
命令提交事务,使更改永久保存。- 回滚事务:如果发生错误,使用
ROLLBACK
命令回滚事务,撤销所有未提交的更改。
COMMIT;
或
ROLLBACK;
5. 使用保存点(可选)
- 使用
SAVEPOINT
创建事务内的保存点,可以部分回滚到某个保存点。
SAVEPOINT savepoint_name;
-- 执行一些操作
ROLLBACK TO SAVEPOINT savepoint_name;
-- 继续其他操作
RELEASE SAVEPOINT savepoint_name;
6. 设置自动提交模式(可选)
- 默认情况下,
MySQL
的autocommit
是开启的,每个独立的SQL
语句都会被自动提交。可以通过以下方式关闭自动提交:关闭后,必须手动提交或回滚事务。
SET autocommit = 0;
7. 事务隔离级别(可选)
- 可以设置事务的隔离级别,以控制事务之间的干扰程度。
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL '隔离级别';
其中'隔离级别'格式如下
-- READ UNCOMMITTED(读未提交)
-- READ COMMITTED(读已提交)
-- REPEATABLE READ(可重复读)
-- SERIALIZABLE(串行化)
-------------------------------------------------------------
或
-------------------------------------------------------------
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别';
其中隔离级别格式如下(注意下滑线)
-- READ_UNCOMMITTED(读未提交)
-- READ_COMMITTED(读已提交)
-- REPEATABLE_READ(可重复读)
-- SERIALIZABLE(串行化)
完整示例
START TRANSACTION;
-- 转账操作:从用户A扣款,给用户B加款
UPDATE accounts SET balance = balance - 100 WHERE user_id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE user_id = 'B';
-- 检查余额是否足够,是否有任何错误
SELECT balance FROM accounts WHERE user_id = 'A';
-- 根据条件决定是提交还是回滚
IF (/* 检查条件 */) THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
使用事务可以提高数据操作的可靠性,确保数据的一致性。在
MySQL
中,事务的使用主要包括开始事务、执行操作、提交或回滚事务
。根据业务需求,合理设置事务的隔离级别
和锁机制
,可以有效地管理并发操作。
三、事务隔离级别
(1)分类
事务的隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ UNCOMMITTED (读未提交) | √ | √ | √ |
READ COMMITTED (读已提交) | X | √ | √ |
REPEATABLE READ (可重复读) | X | X | √ |
SERIALIZABLE (串行化) | X | X | X |
(2)实际生活场景示例理解
(2)隔离级别的查看和设置
查看
隔离级别
SELECT @@transaction_isolation;
SELECT @@GLOBAL.transaction_isolation;
------查看全局
的隔离级别
设置
隔离级别① 设置
当前MySQL
链接的隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别;
SESSION
加不加都可以,但是不加的时候,执行后不会马上生效,所以最好加上。② 设置数据库系统
全局或会话
的隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别;
SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别;
或者:
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = 隔离级别;
其中隔离级别格式如下(注意下滑线):
READ_UNCOMMITTED
(读未提交)READ_COMMITTED
(读已提交)REPEATABLE_READ
(可重复读)SERIALIZABLE
(串行化)
SAVEPOINT
的使用节点名:
设置保存点
,要和ROLLBACK
一起使用才有意义
用法:
执行上述代码前:
执行上述代码后:
示例代码:
# 删除表
DROP TABLE IF EXISTS tab_indentity;
# 创建表时设置标识列
CREATE TABLE IF NOT EXISTS tab_indentity(
id INT PRIMARY KEY auto_increment,
NAME VARCHAR(20)
);
# 插入数据
INSERT INTO tab_indentity VALUES(66,"tom");
INSERT INTO tab_indentity VALUES(NULL,"jerry");
INSERT INTO tab_indentity VALUES(NULL,"wang");
# SAVEPOINT 节点名:设置保存点,
# 要和 ROLLBACK 一起使用才有意义
set autocommit = 0;
DELETE FROM tab_indentity WHERE id = 68;
SAVEPOINT a;#设置保存点
DELETE FROM tab_indentity WHERE id = 69;
ROLLBACK TO a;
SELECT * FROM tab_indentity;
四、事务日志
MySQL
的事务日志是确保数据一致性
和持久性
的重要机制,主要用于支持数据库
的事务性操作。事务日志能够记录数据库对事务所做的修改,确保在系统故障后能够进行恢复,保持数据完整性。MySQL
中的事务日志体系主要包括以下几种类型:
(1)分类
(2)使用