当前位置: 首页 > news >正文

Mysql-事务

Mysql-事务

  • 一、事务是什么?
  • 二、事务的特性(ACID)
  • 三、事务的开启
    • 1. Autocommit
    • 2. 开启事务
  • 四、事务并发存在的问题
  • 五、隔离级别
    • 1.查询隔离级别
    • 2.设置隔离级别
  • 总结


一、事务是什么?

事务是一种机制,包含了一组SQL语句。要么同时执行,要么同时不执行

事务是一个整体

如:事务中有10个SQL语句,1234成功5失败 -> 回滚

什么情况下使用事务 -> 如银行转账
A 1000 -> B 1000
1. A - 100
2. B + 100

事务格式

Begin;
SQL 语句
SQL 语句
SQL 语句
commit;

二、事务的特性(ACID)

A - Atomicity 原子性
事务是一个不可再分割的工作单元,要么都发生,要么都不发生

C - Consistency 一致性
事务开始之前和结束之后,数据库的完整性约束没有被破坏。
转账、购物(售出,库存)

I - Isolation 隔离性
多个事务并发执行时,一个事务的执行不能被其他事务干扰。

D - Durability 持久性
事务执行完成之后(commit),数据写入磁盘,不能被回滚。


三、事务的开启

1. Autocommit

设置是否自动提交
ON : 自动提交 -> 直接将数据写入数据库,相当于每次sql执行完都会自动commit
OFF: 禁止自动提交 -> 每一次写操作都需要commit/rollback操作数据才会写入数据库

每一个SQL都会当成一个事务

查看autocommit

root@(none) 10: 57>show variables like 'autocommit';
±--------------±------+
| Variable_name | Value |
±--------------±------+
| autocommit | ON |
±--------------±------+
1 row in set (0.01 sec)

设置禁止自动提交
Autocommit=0/off

commit => 将数据写入磁盘(commit前,数据在内存)
未使用commit退出后数据丢失

设置自动提交
Autocommit=1/on

执行SQL语句时,默认会将SQL当作一个事务执行,所以autocommit=1时,会自动commit操作


2. 开启事务

如果事务中有多个SQL语句,手动开启事务

  • 开启事务
    begin/start transaction
  • 执行SQL
    SQL 语句
    SQL 语句
  • 提交事务
    commit
  • 设置回滚点
    savepoint name
  • 回滚
    rollback [name]

准备工作

CREATE TABLE info(
id INT(10) PRIMARY KEY,
name VARCHAR(40),
money DOUBLE
);

INSERT INTO info VALUES (1,‘A’,1000);
INSERT INTO info VALUES (2,‘B’,1000);
SELECT * FROM info;

测试回滚

root@test 11: 15>begin ;
Query OK, 0 rows affected (0.00 sec)root@test 11: 16>update info set money=money+100 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0root@test 11: 16>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1100 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)(回滚时会彻底撤销当前事务中所有未提交的修改,并终止事务)
root@test 11: 16>rollback;
Query OK, 0 rows affected (0.00 sec)root@test 11: 17>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)

提交测试

root@test 11: 19>begin;
Query OK, 0 rows affected (0.00 sec)root@test 11: 20>update info set money=money+100 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0root@test 11: 20>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1100 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)root@test 11: 20>commit;
Query OK, 0 rows affected (0.00 sec)root@test 11: 20>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1100 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)

设置回滚点

root@test 11: 20>begin;
Query OK, 0 rows affected (0.00 sec)root@test 11: 22>update info set money=money+100 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0root@test 11: 22>savepoint s1;
Query OK, 0 rows affected (0.00 sec)root@test 11: 22>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1200 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)root@test 11: 22>update info set money=money+100 where id=2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0root@test 11: 22>savepoint s2;
Query OK, 0 rows affected (0.00 sec)root@test 11: 23>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1200 |
|  2 | B    |  1100 |
+----+------+-------+
2 rows in set (0.00 sec)root@test 11: 23>insert into info values(3, 'C', 1000);
Query OK, 1 row affected (0.00 sec)root@test 11: 23>savepoint s3;
Query OK, 0 rows affected (0.00 sec)root@test 11: 23>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1200 |
|  2 | B    |  1100 |
|  3 | C    |  1000 |
+----+------+-------+
3 rows in set (0.00 sec)root@test 11: 23>rollback to s2;
Query OK, 0 rows affected (0.00 sec)root@test 11: 24>SELECT * FROM info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1200 |
|  2 | B    |  1100 |
+----+------+-------+
2 rows in set (0.00 sec)

rollback => 回滚+事务结束
rollback to point => 回滚


四、事务并发存在的问题

多个事务同时并发执行时,可能会引发一系列数据一致性问题

  1. 脏读:读到了未提交的数据(更新数据时)
  2. 不可重复读:前后多次读取同一个数据内容不一致(更新数据时)
  3. 幻读:前后多次读取数据,数量的总量不一致(插入/删除数据时)
  4. 丢失更新: 多个事务同时更新同一个数据时,后提交的事务覆盖先提交的事务

五、隔离级别

  1. 读未提交(read uncommitted): 读取尚未提交的数据
    不解决以上任何问题
    安全性最差,性能最好
  2. 读已提交(read committed): 读取已经提交的数据,可以解决脏读
    只能读到已经提交的数据,未提交的不能读取
    Oracle数据中默认的级别
    安全性较差,性能较好
  3. 可重复读 (Repeatable read): 可以解决脏读、不可重复读
    一个事务执行的过程中,多次读取同一个数据,会得到相同的结果
    Mysql默认的隔离级别
    安全性好,性能中等
  4. 串行化(Serializable): 完全避免所有的问题
    事务被一个一个串行执行
    安全性最好,性能差
脏读不可重复读幻读丢失更新
read uncommittedyesyesyesyes
read committednoyesyesyes
Repeatable readnononoyes
Serializablenononono

1.查询隔离级别

查询全局事务隔离级别

select @@global.transaction_isolation;
±-------------------------------+
| @@global.transaction_isolation |
±-------------------------------+
| REPEATABLE-READ |
±-------------------------------+

show global variables like "%isolation%";
±----------------------±----------------+
| Variable_name | Value |
±----------------------±----------------+
| transaction_isolation | REPEATABLE-READ |
±----------------------±----------------+

查询当前会话(Session)的事务隔离级别

select @@session.transaction_isolation;
±--------------------------------+
| @@session.transaction_isolation |
±--------------------------------+
| REPEATABLE-READ |
±--------------------------------+

show session variables like '%isolation';
±----------------------±----------------+
| Variable_name | Value |
±----------------------±----------------+
| transaction_isolation | REPEATABLE-READ |
±----------------------±----------------+


2.设置隔离级别

全局隔离级别仅影响新创建的会话,已存在的会话不受影响

set global transaction isolation level read uncommitted;
select @@global.transaction_isolation;
±-------------------------------+
| @@global.transaction_isolation |
±-------------------------------+
| READ-UNCOMMITTED |
±-------------------------------+

root@(none) 10: 32>set session transaction isolation level reaad uncommitted;
Query OK, 0 rows affected (0.00 sec)
root@(none) 10: 33>select @@session.transaction_isolation;
±--------------------------------+
| @@session.transaction_isolation |
±--------------------------------+
| READ-UNCOMMITTED |
±--------------------------------+


总结

事务通过ACID 特性(原子性、一致性、隔离性、持久性),从根本上保证了数据库操作的可靠性、一致性和并发安全性,是处理关键业务(如金融交易、订单管理、数据同步等)不可或缺的机制

http://www.xdnf.cn/news/1248301.html

相关文章:

  • Nginx入门:高性能Web服务器详解
  • 【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南
  • Claude Code实战体验:AI智能编程助手如何重塑开发工作流?
  • 2. JS 有哪些数据类型
  • Linux的NFS与Autofs配置指南
  • nodejs 编程基础01-NPM包管理
  • 最优化中常见的优化理论
  • Shader开发(七)创建第一个Shader项目
  • 游戏画面总是卡顿怎么办 告别延迟畅玩游戏
  • DDoS 防护的未来趋势AI 如何改变安全行业
  • MySQL 5.7 和 8.0 离线安装教程(图文版适合电脑小白)
  • C++返回值优化(RVO):高效返回对象的艺术
  • 【基础】第八篇 Java 位运算符详解:从基础到实战应用
  • Unknown initial character set index ‘255’,Kettle连接MySQL数据库常见错误及解决方案大全
  • nuxt学习笔记
  • 什么是mysql的垂直分表,理论依据是什么,如何使用?
  • LeetCode 刷题【31. 下一个排列】
  • Apache OFBiz Scrum 组件命令注入漏洞
  • 力扣148:排序链表
  • 不可变集合
  • 笔记学习杂记
  • nordic通过j-link rtt viewer打印日志
  • Linux网络编程:TCP初体验
  • 永磁同步电机的矢量控制
  • Python包安全工程实践:构建安全可靠的Python生态系统
  • Redis类型之String
  • Python深度学习:从入门到进阶
  • ELK是什么
  • 分布式微服务--Nacos持久化
  • linux定时器管理 timer_*系统调用及示例