MySQL事务

事务是数据库操作的一个逻辑单位,由一系列SQL语句组成。这些操作要么全部执行,要么全部不执行,确保数据的一致性和完整性。事务主要用于处理多步操作的复杂业务逻辑,如银行转账、订单处理等场景。

一、事务的ACID特性

事务必须满足ACID特性,这是事务的核心原则:

1. 原子性(Atomicity)

事务是一个不可分割的工作单位,事务中的所有操作要么全部成功执行,要么全部失败回滚。不会出现部分执行的情况。

例如:银行转账时,从A账户扣款和向B账户存款两个操作必须同时成功或同时失败。

2. 一致性(Consistency)

事务执行前后,数据库从一个一致性状态转换到另一个一致性状态。数据必须满足预设的规则(如约束、触发器等)。

例如:转账前后,A和B两个账户的总金额保持不变。

3. 隔离性(Isolation)

多个事务并发执行时,一个事务的操作不会被其他事务干扰,各个事务之间相互隔离。

MySQL通过隔离级别控制事务之间的可见性,避免并发问题。

4. 持久性(Durability)

事务一旦提交,其对数据库的修改就是永久性的,即使系统崩溃也不会丢失。

MySQL通过将数据写入磁盘实现持久性。

二、事务的操作语句

MySQL中,事务操作主要通过以下语句实现:

1. 开始事务

START TRANSACTION;  -- 或 BEGIN;

功能:标记一个事务的开始,之后的SQL语句将作为事务的一部分。

2. 提交事务

COMMIT;

功能:将事务中所有的修改永久保存到数据库中,事务正常结束。

3. 回滚事务

ROLLBACK;

功能:取消事务中所有的修改,恢复到事务开始前的状态,事务异常结束。

4. 保存点

SAVEPOINT 保存点名称;  -- 创建保存点
ROLLBACK TO SAVEPOINT 保存点名称;  -- 回滚到指定保存点
RELEASE SAVEPOINT 保存点名称;  -- 删除保存点

功能:在事务中创建中间点,允许部分回滚而不是回滚整个事务。

示例:完整的事务流程

-- 开始事务
START TRANSACTION;

-- 执行操作(例如转账)
UPDATE accounts SET balance = balance - 100 WHERE id = 1;  -- 账户1扣款
UPDATE accounts SET balance = balance + 100 WHERE id = 2;  -- 账户2收款

-- 检查操作是否正确(实际应用中可能有更复杂的判断)
-- 如果正确,提交事务
COMMIT;

-- 如果出错,回滚事务
-- ROLLBACK;

三、事务的自动提交机制

MySQL默认启用自动提交(AUTOCOMMIT)模式,即每条SQL语句都会被视为一个独立的事务并自动提交。

1. 查看自动提交状态

SELECT @@AUTOCOMMIT;  -- 1表示启用,0表示禁用

2. 禁用自动提交

SET AUTOCOMMIT = 0;  -- 禁用自动提交,需手动COMMIT或ROLLBACK

3. 注意事项

- 禁用自动提交后,所有SQL语句都属于当前事务,直到执行COMMIT或ROLLBACK

- 执行DDL语句(如CREATE、ALTER、DROP)会自动提交当前事务,不受AUTOCOMMIT设置影响

四、事务的隔离级别

并发事务可能导致的问题包括:脏读、不可重复读、幻读。MySQL通过设置隔离级别解决这些问题。

1. 并发事务的问题

- 脏读(Dirty Read):一个事务读取到另一个未提交事务的修改数据

- 不可重复读(Non-repeatable Read):一个事务中多次读取同一数据,结果不一致(被其他事务修改并提交)

- 幻读(Phantom Read):一个事务中多次查询,结果集的行数不一致(被其他事务插入或删除并提交)

2. MySQL的隔离级别

MySQL支持四种隔离级别(从低到高):

(1)读未提交(READ UNCOMMITTED)

允许读取未提交的事务数据,可能导致脏读、不可重复读、幻读。

性能最高,但安全性最低。

(2)读已提交(READ COMMITTED)

只能读取已提交的事务数据,避免脏读,但可能出现不可重复读、幻读。

是许多数据库的默认隔离级别(如Oracle)。

(3)可重复读(REPEATABLE READ)

保证同一事务中多次读取同一数据的结果一致,避免脏读和不可重复读,但可能出现幻读。

是MySQL InnoDB引擎的默认隔离级别。

(4)串行化(SERIALIZABLE)

最高隔离级别,事务串行执行,避免所有并发问题,但性能最低。

3. 隔离级别的相关操作

查看当前会话的隔离级别
SELECT @@SESSION.TRANSACTION_ISOLATION;

查看全局的隔离级别
SELECT @@GLOBAL.TRANSACTION_ISOLATION;

设置当前会话的隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别名称;

设置全局的隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别名称;

示例:设置当前会话为读已提交级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

五、事务的使用场景

事务适用于需要保证多个操作原子性的场景,典型包括:

1. 金融交易:转账、支付等涉及资金变动的操作

2. 订单处理:创建订单、扣减库存、记录交易等组合操作

3. 数据迁移:从一个表移动数据到另一个表,需确保两边数据一致

4. 用户注册:同时创建用户记录、权限记录、初始配置等

六、事务的注意事项

1. 事务应尽可能短,减少锁定资源的时间,提高并发性能

2. 避免在事务中执行不必要的操作,只包含相关的SQL语句

3. 选择合适的隔离级别,平衡安全性和性能需求

4. 注意事务中的锁机制,避免死锁(两个事务互相等待对方释放资源)

5. 确保使用支持事务的存储引擎(如InnoDB),MyISAM引擎不支持事务

6. 事务失败时,使用ROLLBACK而不是手动编写反向操作恢复数据

七、事务与存储引擎

MySQL的事务支持依赖于存储引擎:

InnoDB:支持事务、行级锁、外键等高级特性,是MySQL默认的存储引擎

MyISAM:不支持事务和外键,只支持表级锁,适用于读多写少的场景

MEMORY:数据存储在内存中,不支持事务,重启后数据丢失

因此,使用事务时需确保表使用InnoDB存储引擎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值