1. 事务的应用场景

事务(Transaction)是数据库操作的最小工作单元,保证一组操作要么全部成功,要么全部失败。常见应用场景有:

  • 银行转账:A账户扣款、B账户加款,必须同时成功或失败。
  • 订单处理:下单时扣减库存、生成订单、写入日志,三者需一致。
  • 批量数据处理:如批量插入、更新、删除,需保证原子性。

实战示例:银行转账

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;
COMMIT;
-- 如遇异常可用 ROLLBACK;

2. 什么是存储引擎、与事务的关联

存储引擎简介

存储引擎是MySQL用于管理表数据的底层模块。常见的有:

  • InnoDB:支持事务、行级锁、外键,适合高并发场景。
  • MyISAM:不支持事务,读写性能高,适合读多写少场景。

MyISAM的历史说明

MyISAM在MySQL 5.5(2010年发布)后已被InnoDB取代为默认存储引擎。虽然MyISAM仍可用,但新项目建议优先使用InnoDB,因为其支持事务和更高的数据安全性。

查看表的存储引擎:

SHOW TABLE STATUS LIKE 'table_name';

存储引擎与事务的关系

只有支持事务的存储引擎(如InnoDB)才能使用事务特性。MyISAM等不支持事务,所有操作立即生效,无法回滚。

3. 事务的开启方式

两种开启事务的方式

MySQL支持两种方式手动开启事务:

START TRANSACTION;
-- 执行多条SQL
COMMIT; -- 提交
ROLLBACK; -- 回滚

BEGIN;
-- 执行多条SQL
COMMIT;
ROLLBACK;

说明START TRANSACTIONBEGIN效果一致,推荐使用START TRANSACTION,因为BEGIN也可作为语句块的起始关键字,容易混淆。

事务的自动提交模式(autocommit)

MySQL默认开启自动提交模式(autocommit=1),即每执行一条SQL语句都会自动作为一个独立事务提交。如果需要多条语句作为一个事务执行,需关闭自动提交或手动开启事务。

查看当前自动提交状态:

SELECT @@autocommit;

关闭自动提交:

SET autocommit = 0;
-- 执行多条SQL
COMMIT; -- 或 ROLLBACK
-- 事务结束后可重新开启自动提交
SET autocommit = 1;

实战场景:

  • 自动提交适合简单的单条操作,如单条插入、更新。
  • 复杂业务(如转账、批量操作)需关闭自动提交,保证多条语句的原子性。

全局事务的开启(分布式场景)

全局事务通常用于分布式系统(如XA事务),MySQL支持XA语法:

XA START 'xid';
-- 执行操作
XA END 'xid';
XA PREPARE 'xid';
XA COMMIT 'xid'; -- 或 XA ROLLBACK 'xid';

使用场景:跨多个数据库或服务的分布式一致性需求。

4. 事务的隔离级别

隔离级别表格(含中文解释)

隔离级别脏读不可重复读幻读默认引擎支持中文解释(括号内)
READ UNCOMMITTED(读未提交)InnoDB允许读取未提交数据,最低隔离级别
READ COMMITTED(读已提交)×InnoDB只能读取已提交数据,Oracle默认
REPEATABLE READ(可重复读)××InnoDB(默认)同一事务多次读取结果一致,MySQL默认
SERIALIZABLE(可串行化)×××InnoDB强制事务串行执行,最高隔离级别
  • √:可能发生
  • ×:不会发生

设置隔离级别

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL REPEATABLE READ;

例子说明

脏读(READ UNCOMMITTED)

A事务未提交,B事务能读到A的未提交数据。

-- 事务A
START TRANSACTION;
UPDATE accounts SET balance = 1000 WHERE user_id = 1;

-- 事务B
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT balance FROM accounts WHERE user_id = 1; -- 读到未提交的1000

不可重复读(READ COMMITTED)

同一事务中两次读取同一数据,结果不同。

-- 事务A
START TRANSACTION;
SELECT balance FROM accounts WHERE user_id = 1; -- 第一次读

-- 事务B
START TRANSACTION;
UPDATE accounts SET balance = 900 WHERE user_id = 1;
COMMIT;

-- 事务A
SELECT balance FROM accounts WHERE user_id = 1; -- 第二次读,值变了

幻读(REPEATABLE READ)

同一事务中两次查询范围数据,第二次多了或少了行。

-- 事务A
START TRANSACTION;
SELECT * FROM orders WHERE amount > 1000; -- 查询结果N条

-- 事务B
INSERT INTO orders (amount) VALUES (2000);
COMMIT;

-- 事务A
SELECT * FROM orders WHERE amount > 1000; -- 查询结果N+1条(幻读)

5. 事务相关术语解释

  • 脏读(Dirty Read):一个事务读取到另一个未提交事务的数据。
  • 不可重复读(Non-repeatable Read):同一事务中多次读取同一数据,结果不同。
  • 幻读(Phantom Read):同一事务中两次查询范围数据,第二次多了或少了行。
  • 原子性(Atomicity):事务中的操作要么全部成功,要么全部失败。
  • 一致性(Consistency):事务执行前后,数据保持一致。
  • 隔离性(Isolation):并发事务之间互不影响。
  • 持久性(Durability):事务一旦提交,数据永久保存。

如需进一步了解事务的高级用法或分布式事务实践,可参考官方文档或实际业务场景进行测试。

分类: MySQL 标签: MySQL事务TRANSACTIONBEGIN事务的隔离级别脏读不可重复读幻读

评论

暂无评论数据

暂无评论数据

目录