Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL事务&用户与权限管理

MySQL事务&用户与权限管理方式

作者:重生之我是Java开发战士

本文介绍了事务的概念以及ACID特性,事务能在并发环境中保证数据正确性和一致性,重点介绍了MySQL事务的实现,包括开启和关闭事务、保存点、自动提交/手动提交等,此外,还详细解释了事务的隔离级别和常见问题,并介绍了用户权限管理的重要性及基本操作

一、什么是事务?

事务就是把一组 SQL 打包成一个不可分割的整体:要么全部成功,要么全部失败,允许只执行一半。

举个例子:银行转账

张三给李四转 100 元需要两步:

如果第一步成功、第二步失败,钱就“凭空消失”了。事务就是用来杜绝这种灾难的。

二、ACID 四大特性

事务之所以可靠,全靠 ACID 四大特性保驾护航:

1. Atomicity(原子性)

2. Consistency(一致性)

这是业务最终追求的目标

3. Isolation(隔离性)

4. Durability(持久性)

原子性保证操作不半途而废,一致性保证结果正确,隔离性保证并发不乱,持久性保证数据不丢。

三、为什么要使用事务

事物具备的ACID特性,就是使用事务的原因,在日常的业务场景中有大量的需求要用事务来保证。

支持事物的数据库能够简化编程模型,不需要去考虑各种而样的钱砸错误和并发问题,在使用事务的过程中,要么提交,成功修改,就可以安全的保存,要么回滚,恢复到事务之初。不需要考虑网络异常,服务器宕机等其他因素。

我们经常接触的事务本质上是数据库对ACID模型的一个实现,是为应用层服务的。

四、MySQL 事务应用

MySQL 里只有 InnoDB 支持事务,MyISAM 不支持

show engines;

可以查看MySQL中支持的存储引擎

transactions显示yes,表明InnoDB支持事务

1. 基本语法

-- 开启事务
start transaction;  -- 或 begin;

-- 执行 SQL:insert/update/delete...

-- 提交:永久生效
commit;

-- 回滚:全部撤销
rollback;

2. 转账案例

建表:

 create table account(
 id bigint primary key auto_increment,
 name varchar(20),
 balance decimal(5,2)
 );

insert account values
(1,"张三",1000.00),
(2,"李四",1000.00);

① 事务提交:数据永久修改

start transaction;

update account set balance = balance + 100 where name = "张三";
update account set balance = balance - 100 where name = "李四";

commite;

执行后:张三 1100,李四 900,永久生效。

② 事务回滚:数据回到最初

start transaction;

update account set balance = balance + 100 where name = "张三";
update account set balance = balance - 100 where name = "李四";

rollback;

执行后:数据完全没变,回到最初状态。

3. 保存点 savepoint

事务太长,可以设置“检查点”,回滚到指定位置:

start transaction;

-- 操作1
savepoint sp1;

-- 操作2
savepoint sp2;

-- 回滚到 sp1
rollback to sp1;

-- 回滚全部,关闭事务
rollback;

适合调试、批量操作、分步撤销。

4. 自动提交 / 手动提交

MySQL 默认 自动提交(每条 SQL 自成事务):

-- 查看
show variables like 'autocommit';

-- 关闭自动提交(手动控制)
set autocommit = 0;

-- 开启自动提交
set autocommit = 0;

显示on,表示自动提交已打开,可以手动设置为关闭。

注意:

1.只要使用 begin / start transaction开启事务,就必须使用 commit / rollback 才能结束事务。

2.手动提交模式下,不会显示开启事务,但是需要手动 commit / rollback来结束事务

3.自动提交打开时,一个事务只包含一个DML语句

DML语句是指updateinsertdelete等数据操作语言

4.DDL 语句会强制提交事务

DDL语句是对库、表、结构做定义、修改、删除的数据定义语言

如果在事务里执行 create database / create table / alter table/ drop table 这类 DDL,事务会被自动提交,后面的 SQL 就不在这个事务里了,也无法回滚前面的操作。

5.设置手动提交,如果重启电脑会恢复成自动提交,如果想要永久设置成手动提交,可以在配置文件中修改

五、事务的隔离性与隔离级别

5.1 什么是隔离性

MySQL服务可以同时被多个客户端访问,每个客户端执行的DML语句是以事务为单位,那么不同的客户端都同一张表的同一条数据进行修改的时候可能出现相互影响的情况。

为了保证不同的事务之间执行过程不受影响,那么事物之间需要相互隔离,这种特性就是隔离性

5.2 隔离级别

事物的隔离级别描述了事务之间的隔离程度。

不同的隔离级别在性能和安全方面做了取舍,有的隔离界别注重并发性,有的注重安全性,有的则是安全与并发适中。

在MySQL的InnoDB引擎中事务的隔离界别有四种,安全性逐渐增强,性能逐渐减弱:

5.3 不同隔离级别存在的问题

多个事务同时跑,会出现 3 种经典数据错乱:

1. 脏读 Dirty Read

事务A读到事务B没提交的数据,如果事务B回滚,事务A读到的就是“假数据”。

2. 不可重复读 Non-Repeatable Read

在同一个事务A内,多次读取同一行数据,期间数据被另一个已提交的事务B修改,导致多次读取结果不一致。这种现象就是不可重复读

3. 幻读 Phantom Read

同一个事务内,两次范围查询条数不一样。InnoDB 用 Next-Key 锁,锁住了目标行和之前的“间隙”,解除了部分幻读问题

serializable 串行化解决了所有数据安全问题,所有事务一个挨一个执行,同时效率也是最低的。

隔离级别脏读不可重复读幻读性能
READ UNCOMMITTED(读未提交)✅ 有✅ 有✅ 有最快
READ COMMITTED(读已提交)❌ 无✅ 有✅ 有
REPEATABLE READ(可重复读)❌ 无❌ 无✅ 有中等
SERIALIZABLE(串行化)❌ 无❌ 无❌ 无最慢

5.4 查看 / 设置 隔离界别

-- 全局作用域
select @@global.transaction_isolation;

-- 局部作用域
select @@session.transaction_isolation

-- 设置会话级别
set session transaction isolation level read committed;

六、用户权限管理

在实际开发中,数据库绝对不能所有人都用 root 账号乱操作。用户隔离 + 权限控制是安全的第一道防线。

6.1 为什么要做用户与权限管理?

6.2 用户基础操作

MySQL 的用户信息存在 mysql 库的 user 表中。

1. 查看所有用户

use mysql;
select host, user, authentication_string from user;

2. 创建用户

CREATE USER '用户名'@'允许登录地址' IDENTIFIED BY '密码';

常用示例:

-- 只能本机登录
CREATE USER 'test'@'localhost' IDENTIFIED BY '123456';

-- 允许 192.168.1.x 网段登录
CREATE USER 'test'@'192.168.1.1/24' IDENTIFIED BY '123456';

注意:

3. 修改密码

-- root 给别人改密
ALTER USER 'bit'@'localhost' IDENTIFIED BY '987654';

-- 自己改自己密码
SET PASSWORD = '111111';

4. 删除用户

DROP USER 'bit1'@'192.168.1.1/24';

6.3 权限管理:授权与回收

新建用户默认没有任何权限,只能看见系统库,必须手动授权。

1. 常用权限

2. 授权语法

GRANT 权限 ON 库.表 TO '用户'@'地址';

常用示例:

-- 给 test 用户授权 java01 库所有表的 查询权限
GRANT SELECT ON java01.* TO 'test'@'localhost';

-- 给 test 用户授权 java01 库所有权限(增删改查)
GRANT ALL ON java01.* TO 'test'@'localhost';

授权后需要刷新:

FLUSH PRIVILEGES;
``
### 3. 查看用户权限
```sql
SHOW GRANTS FOR 'test'@'localhost';

4. 回收权限

-- 回收所有权限
REVOKE ALL ON *.* FROM 'test'@'localhost';

FLUSH PRIVILEGES;

6.4 标准流程

-- 1. 创建专用用户(本机登录)
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'App@123456';

-- 2. 授权指定库的所有权限
GRANT ALL ON mydb.* TO 'appuser'@'localhost';

-- 3. 刷新权限
FLUSH PRIVILEGES;

-- 4. 查看权限
SHOW GRANTS FOR 'appuser'@'localhost';

-- 5. 回收(不需要时)
REVOKE ALL ON *.* FROM 'appuser'@'localhost';
FLUSH PRIVILEGES;

-- 6. 删除用户
DROP USER 'appuser'@'localhost';

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文