MySQL数据库--事务

这篇具有很好参考价值的文章主要介绍了MySQL数据库--事务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中, 要删除一个人员,即需要删除人员的基本资料,又需要删除和该人员相关的信息,如信箱, 文章等等。这样,这些数据库操作语句就构成一个事务!


一、事物的概念

  • 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。

  • 事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。

  • 事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等。

  • 事务是通过事务的整体性以保证数据的一致性。

说白了,所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

二、事务的ACID特点

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)应该具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这是可靠数据库所应具备的几个特性。

  1. 原子性:
  • 指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。

  • 事务是一个完整的操作,事务的各元素是不可分的。

  • 事务中的所有元素必须作为一个整体提交或回滚。

  • 如果事务中的任何元素失败,则整个事务将失败。

  • 案例:
    A给B转帐100元钱的时候只执行了扣款语句,就提交了,此时如果突然断电,A账号已经发生了扣款,B账号却没收到加款,在生活中就会引起纠纷。这种情况就需要事务的原子性来保证事务要么都执行,要么就都不执行。

  1. 一致性:
  • 指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

  • 当事务完成时,数据必须处于一致状态。

  • 在事务开始前,数据库中存储的数据处于一致状态。

  • 在正在进行的事务中,数据可能处于不一致的状态。

  • 当事务成功完成时,数据必须再次回到已知的一致状态。

  • 案例:
    对银行转帐事务,不管事务成功还是失败,应该保证事务结束后表中A和B的存款总额跟事务执行前一致。

  1. 隔离性:
  • 指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。

  • 对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。
    修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据。

一个事务的执行不能被其他事务干扰

  1. 持久性:
  • 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

  • 指不管系统是否发生故障,事务处理的结果都是永久的。
    一旦事务被提交,事务的效果会被永久地保留在数据库中。

  1. 事务之间的相互影响分为几种,分别为
  • 脏读(读取未提交数据):
    脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读

    • 案列1
      比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。 也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。
  • 不可重复读(前后多次读取,数据内容不一致):
    一个事务内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。

    • 案列
      事务A第一次查询得到一行记录row1,事务B提交修改后,事务A第二次查询得到row1,但列内容发生了变化。
select * from member;
1 zhangsan  20分
select * from Member;
1 zhangsan  30分

  • 幻读(前后多次读取,数据总量不一致):
    一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,操作前一个事务的用户会发现表中还有没有修改的数据行,就好象发生了幻觉一样。

    • 案列
      假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读
      select * from member;
      查询到了6条记录
alter table member change

select * from member;
查询到了10条记录 (更新了6条数据,还有4条数据,我没有更新到)

  • 丢失更新:
    两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。
    • 案列
      A 30 ->40 事务 先完成
      B 30 ->50 事务 后完成
      B的事务结果会覆盖A的事务结果,最终值为50

三、Mysql及事务隔离级别(四种)

  1. read uncommitted(未提交读) :
  • 读取尚未提交的数据 :不解决脏读
  • 允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数居。
  1. read committed(提交读):
  • 读取已经提交的数据 :可以解决脏读
  • 只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别〈不重复读)。
  1. repeatable read(可重复度):
  • 重读读取:可以解决脏读 和 不可重复读 —mysql默认的
  • 可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响
  1. serializable:串行化:
  • 可以解决 脏读 不可重复读 和 虚读—相当于锁表
    -完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

mysql默认的事务处理级别是 repeatable read ,而Oracle和SQL Server是 read committed 。

  1. 事务隔离级别的作用范围(2种)
  • 全局级:对所有的会话有效(全局级配置会在进入数据库中加载到会话级中,全局配置重启生效)

  • 会话级:只对当前的会话有效(立即生效)

  • 查询全局事务隔离级别

set global transaction isolation level read committed;
#例:
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like '%isolation%';	
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| tx_isolation  | READ-COMMITTED |		//已经改为提交读
+---------------+----------------+
1 row in set (0.00 sec)


  • 置会话事务隔离级别
set session transaction isolation level read committed;
#例:
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

mysql> show session variables like '%isolation%';
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| tx_isolation  | READ-COMMITTED |		//查看已经更改为提交读
+---------------+----------------+
1 row in set (0.00 sec)



四、事务控制语句

BEGIN 或 START TRANSACTION:显式地开启一个事务。

COMMIT 或 COMMIT WORK:提交事务,并使已对数据库进行的所有修改变为永久性的。

ROLLBACK 或 ROLLBACK WORK:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。

SAVEPOINT S1:使用 SAVEPOINT 允许在事务中创建一个回滚点,一个事务中可以有多个 SAVEPOINT;“S1”代表回滚点名称。

ROLLBACK TO [SAVEPOINT] S1:把事务回滚到标记点。

  • 模板:
mysql> create database test;		//创建test库
Query OK, 1 row affected (0.00 sec)

mysql> use test;		//切换到test
Database changed

mysql> create table info(		//创建info表
    -> id int(10) primary key not null,
    -> name varchar(40),
    -> money double
    -> );
Query OK, 0 rows affected (0.15 sec)


mysql> insert into info values(1,'A',1000);		//添加数据
Query OK, 1 row affected (0.00 sec)

mysql> insert into info values(2,'B',1000);		//添加数据
Query OK, 1 row affected (0.00 sec)

mysql> select * from info;		//查询数据
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec

  1. 测试提交事务
mysql> begin;		//开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> update info set money= money - 100 where name='A';	//事务
select * from info;

mysql> commit;		//提交事务

###退出重进
quit
mysql -u root -p	
use SCHOOL;

mysql> select * from info;		//数据已经被更改
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |   900 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)

  1. 测试回滚事务
mysql> select * from info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |   900 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)begin;

mysql> begin;		//开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> update info set money= money + 100 where name='A';	//修改数据
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from info;	//查看
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)

mysql> rollback;		//回滚
Query OK, 0 rows affected (0.00 sec)

####退出重进
mysql> quit
mysql -u root -p
mysql> use SCHOOL;
mysql> select * from info;	//再次查看,数据已经回滚
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |   900 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)


  1. 测试多点回滚
mysql> begin;		//开启事务

mysql> update info set money= money + 100 where name='A';	//修改更新数据

mysql> select * from info;	//查看数据
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)

mysql> savepoint s1;		//创建回滚点s1 
Query OK, 0 rows affected (0.00 sec)

mysql> update info set money= money + 100 where name='B';	//修改更新数据

mysql> select * from info;
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1100 |
+----+------+-------+
2 rows in set (0.00 sec)

mysql> savepoint s2;	//创建回滚点s2
Query OK, 0 rows affected (0.00 sec)

mysql> insert into info values(3,'C',1000);		//插入新数据
Query OK, 1 row affected (0.00 sec)

mysql> select * from info;	
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1100 |
|  3 | C    |  1000 |
+----+------+-------+
3 rows in set (0.00 sec)

mysql> rollback to s1;		//回滚到s1
Query OK, 0 rows affected (0.00 sec)

mysql> select * from info;	//再次查看发现数据已经回滚
+----+------+-------+
| id | name | money |
+----+------+-------+
|  1 | A    |  1000 |
|  2 | B    |  1000 |
+----+------+-------+
2 rows in set (0.00 sec)


  1. 使用 set 设置控制事务
SET AUTOCOMMIT=0;						#禁止自动提交
SET AUTOCOMMIT=1;						#开启自动提交,Mysql默认为1
SHOW VARIABLES LIKE 'AUTOCOMMIT';		#查看Mysql中的AUTOCOMMIT值
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)

如果没有开启自动提交,当前会话连接的mysql的所有操作都会当成一个事务直到你输入rollback|commit;当前事务才算结束。当前事务结束前新的mysql连接时无法读取到任何当前会话的操作结果。
如果开起了自动提交,mysql会把每个sql语句当成一个事务,然后自动的commit。
当然无论开启与否,begin; commit|rollback; 都是独立的事务。

use SCHOOL;
select * from info;
SET AUTOCOMMIT=0;		//禁止自动提交
SHOW VARIABLES LIKE 'AUTOCOMMIT';	//查看Mysql中的AUTOCOMMIT值
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | NO    |
+---------------+-------+
update info set money= money + 100 where name='B';
select * from info;
quit

mysql -u root -p
use SCHOOL;
select * from info;

总结

  • 事物的ACID特点为:原子性、一致性、隔离性、持久性

  • 事务之间的相互影响分为:脏读、不可重复读、幻读、丢失更新

  • 事务隔离级别分为:read uncommitted(未提交读)、read committed(提交读)、repeatable read(可重复度)、serializable:串行化

  • mysql默认的事务处理级别是 repeatable read

  • 事务隔离级别的作用范围分为
    全局级:对所有的会话有效
    会话级:只对当前的会话有效文章来源地址https://www.toymoban.com/news/detail-506944.html

到了这里,关于MySQL数据库--事务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Mysql数据库 第13章】MySQL的事务、事务的隔离级别、事务的保存点

    💖Spring中的创建对象的三种方式、第三方资源配置管理详细描述及使用(XML版完结篇) 💖Spring中的bean的配置、作用范围、生命周期详细描述及使用(XML版上篇) 💖

    2023年04月20日
    浏览(57)
  • 【MySQL数据库 | 第十五篇】事务

        目录    前言:  介绍事务:  控制事务:  事务四大特性:  并发事务问题:  事务隔离级别: 总结:   这章我们将进入到MySQL基础篇的最后一章:事务,希望大家可以坚持下去,跟着我一起走完MySQL的学习之旅。 MySQL是一种关系型数据库管理系统,支持事务管理。 事

    2024年02月08日
    浏览(57)
  • 用于将Grafana默认数据库sqlite3迁移到MySQL数据库

    以下是一个方案,用于将Grafana数据迁移到MySQL数据库。 背景: grafana 默认采用的是sqlite3,当我们要以集群形式部署的时使用mysql较为方便,试了很多sqlite转mysql的方法要么收费,最后放弃。选择自己动手风衣足食。 目标: 迁移sqlite3切换数据库到mysql 前提条件: 确保你已经安装了

    2024年02月20日
    浏览(64)
  • 【Spring/MySQL数据库系列】数据库事务的特点与隔离级别

    ⭐️ 前面的话 ⭐️ 本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍有关数据库事务的特点以及隔离级别。 📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📌本文由 未见花闻 原创, CSDN 首发! 📆首发时间:🌴2023年5月20日🌴 ✉️坚

    2024年02月05日
    浏览(55)
  • Go 语言实现 MySQL 数据库事务

    MySQL事务是指一组数据库操作,它们被视为一个逻辑单元,并且要么全部成功执行,要么全部回滚(撤销)。事务是数据库管理系统提供的一种机制,用于确保数据的一致性和完整性。 事务具有以下特性(通常由ACID原则定义): 原子性(Atomicity):事务中的所有操作要么全

    2024年02月08日
    浏览(47)
  • C# 从代码入门 Mysql 数据库事务

    在业务开发中,使用数据库事务是必不可少的。而开发中往往会使用各种 ORM 执行数据库操作,简化代码复杂度,不过,由于各种 ORM 的封装特性,开发者的使用方式也不一样,开发者想要了解 ORM 对事务做了什么处理是比较难的。因此,本文介绍数据库事务基础、Ado.net 事务

    2024年02月04日
    浏览(55)
  • 【后端面经-数据库】MySQL的事务隔离级别简介

    目录 0. 事务的概念 1. 三类问题 2. 事务隔离级别 3. 操作指令 4. 总结 5. 参考博文 事务指的是一连串的集中操作指令,一个事务的执行必须执行完所有的动作才能算作执行结束。事务具有四个特点,简记作 ACID : A -Atomicity: 原子性,事务的执行必须保证所有的动作都执行完毕;

    2024年02月08日
    浏览(49)
  • 【MySQL】一文带你了解数据库索引与事务

    数据库索引是一种提高数据库查询效率的数据结构。它可以快速地定位和访问数据库中的数据,从而大大提高数据库查询的速度和效率。数据库索引可以根据不同的查询需求构造多个索引,以最大化提高查询效率。 数据库索引基于各种字段来创建,在查询时可以通过索引直接

    2024年02月09日
    浏览(49)
  • 初识mysql数据库之事务的概念及操作

    目录 一、数据库多客户端访问问题 1. 数据库的CURD无限制带来的问题 2. 如何解决CURD导致的问题 二、事务的概念 1. 什么是事务 2. 事务的四个属性 3. mysql对事务的管理 4. 为什么会有事务 5. 事务的版本支持 三、事务的操作 1. 事务提交方式 2. 事务操作的准备工作 2.1 数据库是网

    2024年02月15日
    浏览(44)
  • MySQL:事务、索引、用户管理、备份、数据库设计(三大范式)

    事务 (transaction):要么都成功,要么都失败。 核心 :将一组 SQL 放在一个批次中去执行。 原则 ACID :原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。 原子性 :一个事务中的所有步骤 要么都 成功, 要么都 失败,不能只成功一个步骤。 一致性 :包括

    2023年04月26日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包