MySQL 基础(四):用户权限、事务 ACID 与隔离级别
1151 字
6 分钟
MySQL 基础(四):用户权限、事务 ACID 与隔离级别
1. DCL:用户与权限
用户由“用户名 + 主机”共同标识,例如 'report_user'@'localhost' 和 'report_user'@'%' 是两个不同账号。
1.1 用户管理
-- 查看用户SELECT User, Host FROM mysql.user;
-- 创建仅允许本机访问的用户CREATE USER 'report_user'@'localhost'IDENTIFIED BY '请替换为高强度密码';
-- 修改密码ALTER USER 'report_user'@'localhost'IDENTIFIED BY '请替换为新的高强度密码';
-- 删除用户DROP USER 'report_user'@'localhost';IDENTIFIED WITH mysql_native_password 是指定认证插件的兼容性写法。没有旧客户端兼容要求时,通常只写 IDENTIFIED BY,让服务器使用默认认证插件。
1.2 权限控制
-- 查看权限SHOW GRANTS FOR 'report_user'@'localhost';
-- 仅授予查询权限GRANT SELECT ON mysql_learn.*TO 'report_user'@'localhost';
-- 授予多项权限GRANT SELECT, INSERT, UPDATE ON mysql_learn.empTO 'app_user'@'10.%';
-- 撤销权限REVOKE INSERT, UPDATE ON mysql_learn.empFROM 'app_user'@'10.%';安全原则:
- 遵循最小权限原则,不轻易授予
ALL PRIVILEGES。 - 生产应用不要使用
root连接数据库。 '%'表示任意主机,范围很大,应结合网络、防火墙和 TLS 策略谨慎使用。- 密码不要写入代码仓库或命令历史,应使用安全的配置和密钥管理方式。
2. 事务
2.1 事务的作用
事务是一组不可分割的操作,要么全部成功,要么全部失败。典型场景是转账:付款方扣款和收款方加款必须作为一个整体。
默认情况下,MySQL 通常开启自动提交,每条独立 DML 语句执行后会自动提交:
SELECT @@autocommit;2.2 基本控制
推荐显式开启事务:
START TRANSACTION;
UPDATE accountSET money = money - 1000WHERE id = 1;
UPDATE accountSET money = money + 1000WHERE id = 2;
COMMIT;-- 发生异常时执行 ROLLBACK;也可以修改当前会话的自动提交:
SET SESSION autocommit = 0;COMMIT;SET SESSION autocommit = 1;长期关闭自动提交容易忘记提交或回滚,学习和业务代码中通常更推荐明确的事务边界。
2.3 SAVEPOINT
保存点可以只回滚事务的一部分:
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE id = 1;SAVEPOINT after_debit;
UPDATE account SET money = money + 100 WHERE id = 2;
ROLLBACK TO SAVEPOINT after_debit;RELEASE SAVEPOINT after_debit;COMMIT;ROLLBACK TO SAVEPOINT 不会结束整个事务;最终仍需 COMMIT 或 ROLLBACK。
2.4 ACID
| 特性 | 含义 |
|---|---|
| Atomicity,原子性 | 事务中的操作要么全部成功,要么全部失败 |
| Consistency,一致性 | 事务前后数据必须满足业务规则和约束 |
| Isolation,隔离性 | 并发事务之间尽量互不干扰 |
| Durability,持久性 | 事务提交后的结果应被持久保存 |
回滚是原子性的表现;“持久性”主要指提交后的改变。课程原文中“提交或回滚后的改变永久”表述不够严谨,因为回滚的目标是撤销未提交的改变。
2.5 并发事务问题
| 问题 | 含义 |
|---|---|
| 脏读 | 读到其他事务尚未提交的数据 |
| 不可重复读 | 同一事务两次读取同一行,值发生变化 |
| 幻读 | 同一事务按相同条件查询,返回的行集合发生变化 |
2.6 隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读(SQL 标准定义) |
|---|---|---|---|
READ UNCOMMITTED | 可能 | 可能 | 可能 |
READ COMMITTED | 避免 | 可能 | 可能 |
REPEATABLE READ | 避免 | 避免 | 可能 |
SERIALIZABLE | 避免 | 避免 | 避免 |
InnoDB 默认使用 REPEATABLE READ,并通过 MVCC、间隙锁等机制处理许多并发场景;具体表现还取决于查询是否为快照读、当前读以及是否使用索引。
-- 查看当前会话隔离级别SELECT @@transaction_isolation;
-- 设置当前会话隔离级别SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;隔离级别越高,并发能力通常越低。应根据一致性要求和访问模式选择,而不是简单追求最高级别。
2.7 转账示例的进一步完善
转账还需要考虑余额不足和并发扣款。可在事务中锁定账户行:
START TRANSACTION;
SELECT id, moneyFROM accountWHERE id IN (1, 2)ORDER BY idFOR UPDATE;
-- 应用层确认付款方余额充足后再执行UPDATE accountSET money = money - 1000WHERE id = 1 AND money >= 1000;
UPDATE accountSET money = money + 1000WHERE id = 2;
COMMIT;实践要点:
- 金额字段使用
DECIMAL,不要使用DOUBLE。 - 应检查扣款语句影响行数,若为 0 则回滚。
- 多行加锁时采用一致顺序,可降低死锁概率。
- 事务尽量短,不要在事务中等待用户输入或执行耗时外部调用。
CREATE、ALTER、DROP、TRUNCATE等 DDL 通常会触发隐式提交,不要把它们当成普通 DML 回滚。














