SQL基础理论篇(十):事务处理

文章目录

  • 简介
  • 事务的四大特性ACID
  • 如何使用事务
  • 参考文献

简介

MySQL在5.5版本之前,默认的存储引擎是MyISAM,它是不支持事务的,而5.5版本之后默认的引擎是InnoDB,这个是支持事务的,这也是InnoDB最终取代MyISAM称为主流引擎的重要原因。

事务的真实情况,比我下面写的还要更复杂,所以需要另外再自行查找资料。

事务,即transaction,是数据库的一个逻辑工作单元,是一组不可分割的操作集合,也是数据库进行一次处理的基本单元,要不完全执行,要么都不执行。

事务是数据库区别于文件系统的重要特性之一。有了事务,我们可以保证数据库始终保持一致性;有了事务,我们可以使得数据库恢复到任意有记录的时间点;有了事务,我们可以保证已经提交的修改不会因为中途断电而丢失(不完整)。

事务的四大特性ACID

事务的四大特性:ACID。

  • A,即Atomicity,原子性。原子性意味着不可分割,是进行数据处理操作的最小单位;
  • C,即Consistency,一致性。数据库在进行事务操作后,会由原来的一致状态,变成另一种一致状态。就是说事务提交后,或事务发生回滚后,数据库的完整性约束不能被破坏。
  • I,即Isolation,隔离性。每个事务是彼此独立的,不会受到其他事务的影响。一个事务在提交之前,对其他事务都是不可见的。
  • D,即Durability,持久性。事务提交后,对数据库的修改是持久的。即使系统出现故障、比如系统崩溃,数据的修改依旧是有效的。因为当事务完成,数据库的日志就会被更新,这时可以通过日志来使系统恢复到最后一次成功的更新状态。

这四个特性中,原子性是基础,隔离性是手段,一致性是约束条件,持久性是目的。

比较难理解的是一致性和持久性。

一致性,意味着任何写入数据库的数据都需要满足我们事先定义的约束规则

比如说,事先我们设置name字段为唯一性约束(如主键约束),如果事务提交后或者回滚的时候,若name非唯一,就算打破了事务的一致性要求。

数据库常见的约束有:

  • 主键约束:主键(一个字段或多个字段)唯一标识一条记录,不能重复,不能为空;
  • 外键约束:确保了表与表之间引用的完整性,一个表的外键对应着另一张表的主键(也可以不是主键,但字段必须有唯一性约束);
  • 唯一性约束:字段在表中的值是唯一的。需要注意的是,唯一性约束和普通索引是有区别的。创建唯一性约束的时候会自动创建一个约束和字段的普通索引,目的是为了保证字段的正确性,而普通索引只是为了提升数据检索的速度。
  • 非空约束:对字段约束not null;
  • default约束:表明字段的默认值;
  • check约束:检查特定字段取值范围的有效性,check约束的检查结果不能是false。比如我们将身高字段进行check约束,比如小于180,大于160。

事务执行前,数据库符合这些约束,事务执行后,数据库同样需要符合这些约束,这就是事务的一致性。如果事务中的某个操作执行失败了,系统就会自动回滚,撤销当前执行的事务,返回事务操作之前的一致性状态。

持久性,持久性是通过事务日志来保证的。事务日志包括回滚日志和重做日志。当我们通过事务对数据进行修改的时候,首先会将数据库需要做的修改信息记录到重做日志中,然后再对数据库中相应的行做改变。这样的好处是,如果执行中途数据库发生了故障而崩溃了,数据库重启后也能找到重做日志,重新执行没有执行完的修改,从而使事务具有了持久性。(提交之后100%会被执行完毕,即使数据库崩了,重启之后照样给你写进去。)

如何使用事务

首先你需要有一个支持事务的数据库引擎。

以MySQL举例,InnoDB引擎是支持事务的,但是MyISAM引擎就不支持事务。我们可以通过show engines来查看当前的MySQL支持的存储引擎都有哪些,以及这些引擎是否支持事务。

常见的事务控制语句有:

  • start transaction或者begin,作用是显式的开启一个事务;
  • commit:显式的提交一个事务。当提交事务后,对数据库的修改是永久的。(持久性)
  • rollback或者rollback to [savepoint],回滚事务,撤销当前正在进行的所有没有提交的修改,或者将事务回滚到某个保存点;
  • savepoint:在事务中创建保存点,方便后续针对某个保存点进行回滚。一个事务中可以存在多个保存点。
  • release savepoint:删除某个保存点;
  • set transaction:设置事务的隔离级别。

使用事务有两种方式,分别为隐式事务和显式事务。

隐式事务实际上就是自动提交。Oracle中默认是不支持自动提交的,需要手写commit来显式提交。MySQL中默认自动提交(通过set autocommit =0或1来关闭开启自动提交)。

让我们看几个例子:

-- autocommit=1,即自动提交开启
CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
BEGIN;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

上面其实执行了两个事务。第一个事务insert了关羽,然后正常commit了。第二个事务在第一个insert的时候正常,但是第二个insert插入张飞,打破了事务的主键约束,所以回滚整个事务。因此最终的表里只有一行“关羽”。

然后第二个例子:

-- autocommit=1,即自动提交开启
CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

由于自动commit的情况,上面实际上执行了三个事务。第一个是显式begin的那个事务,成功插入了一行关羽。第二个事务是第二个insert,因为自动提交,所以这个“张飞”也成功插入了。第三个事务是第三个insert,由于主键约束,insert失败,因此回滚了第三个事务。

事务在commit之后,就没法再回滚了!!! 那如果开了自动commit的话,除非事务出错,才会引起自动回滚,显式rollback是没用的?是这样理解吗?

第三个例子:

CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
SET @@completion_type = 1;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

在MySQL中,如果是连续BEGIN,开启了第一个事务,还没有进行COMMIT提交,而直接进行第二个事务的BEGIN,数据库会隐式的帮助COMMIT第一个事务,然后进入到第二个事务

第三个例子跟第二个例子只有一点不同,就是多了一个@@completion_type这个变量。这个参数的取值及作用有3种可能:

  • completion_type = 1,当提交事务后,相当于执行了commit;begin,提交事务后会再开启一个相同隔离级别的链式事务。
  • completion_type = 2,commit操作相当于commit and release,提交后会自动与服务器断开连接;
  • completion_type=0,默认情况,commit就是普通的提交事务,下一个事务还需要自己开。

所以上面的例子,实际上只插入了关羽一行,因为第一个commit = commit and begin,后面两个insert被自动包括进一个事务了。

当设置autocommit=0的时候,取消自动提交,那么不论是否采用begin的方式显示开启事务,都需要手动commit来提交,使得事务生效,使用rollback来对事务回滚。

不过,当设置autocommit=1的时候,允许自动提交,那当显式使用start transaction或者begin的方式开启事务时,只有在显式commit的时候才会生效,显式rollback的时候才会回滚

在MySQL中,当取消自动提交时,连续begin,第二个begin会自动commit第一个事务,保证每次只处理一个事务。

2021-7-4 17:15:01 事务这里还是很重要的,推荐后续大块时间走一遍

参考文献

  1. 14丨什么是事务处理,如何使用COMMIT和ROLLBACK进行操作?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/196791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode配置使用 cpplint

标题安装clang-format和cpplint sudo apt-get install clang-format sudo pip3 install cpplint标题以下settings.json文件放置xxx/Code/User目录 settings.json {"sync.forceDownload": false,"workbench.sideBar.location": "right","…

振动和震动的区别?

问题描述:振动和震动的区别? 问题解决: 震动(Oscillation): 特点: 随机的、突发的、不经常的、无规律的运动。例子: 地壳震动、消息震动全国,强调的是运动的力度或幅度&…

Using Application Engine Meta-SQL 使用应用引擎元SQL

Using Application Engine Meta-SQL 使用应用引擎元SQL This section describes the meta-SQL constructs, functions, and meta-variables you can use in Application Engine. 本节描述可以在Application Engine中使用的元SQL构造、函数和元变量。 Note: The SQL Editor does…

RPG项目01_技能释放

基于“RPG项目01_新输入输出”, 修改脚本文件夹中的SkillBase脚本: using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; //回复技能,魔法技能,物理技能…

分类变量组间差异分析

1&#xff0c;频数表列联表 一维频数表 table <- table(data$low) table 0 1 130 59 prop.table(table)#百分比0 1 0.6878307 0.3121693 二维频数表 table1 <- table(data$low,data$smoke) table10 1 0 86 44 1 29 30 addmargins(table1)0 1 Sum 0…

2023.12.3 每日一题 最大点数 很巧秒的做法,数学思维的开拓

1423. 可获得的最大点数 几张卡牌 排成一行&#xff0c;每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动&#xff0c;你可以从行的开头或者末尾拿一张卡牌&#xff0c;最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有卡牌的点数之和。 给你…

java synchronized详解

背景 在多线程环境下同时访问共享资源会出现一些数据问题&#xff0c;此关键字就是用来保证线程安全的解决这一问题。 内存可见的问题 在了解synchronized之前先了解一下java内存模型&#xff0c;如下图&#xff1a; 线程1去主内存获取x的值读入本地内存此时x的值为1&…

React笔记

React 目录结构 入口文件 React是 React 的核心库 ReactDom是提供与 DOM 相关的功能 RegisterServiceWorker加快react的运行速度的一个js文件 ReactDom.render() 渲染页面 React创建组件 render里边放的模板 是HTML和JavaScript的结合 jsx 创建子组件 App.js 根组件文件…

3DMM模型

目录 BFMBFM_200901_MorphableModel.matexp_pca.bintopology_info.npyexp_info.npy BFM BFM_2009 01_MorphableModel.mat from scipy.io import loadmat original_BFM loadmat("01_MorphableModel.mat") # dict_keys: [__header__, __version__, __globals__, # …

视频剪辑转码:mp4批量转成wmv视频,高效转换格式

在视频编辑和处理的领域&#xff0c;转换格式是一项常见的任务。在某些编辑和发布工作中&#xff0c;可能需要使用WMV格式。提前将素材转换为WMV可以节省在编辑过程中的时间和精力。从MP4到WMV的批量转换&#xff0c;不仅能使视频素材在不同的平台和设备上得到更好的兼容性&…

LoadBalancer将服务暴露到外部实现负载均衡Openelb-layer2模式配置介绍

目录 一.openelb简介 二.主要介绍layer2模式 1.简介 2.原理 3.部署 &#xff08;1&#xff09;先在集群master上开启kube-proxy的strictARP &#xff08;2&#xff09;应用下载openelb.yaml&#xff08;需要修改镜像地址&#xff09; &#xff08;3&#xff09;编写yam…

defer 用法

目录 1、资源释放 2、异常捕获 3、参数的预计算 4、defer 返回值的陷阱 1、资源释放 下面是一个简单的读取文件的程序&#xff0c;os.Open 打开文件资源描述符&#xff0c;在读取文件后&#xff0c;需要释放资源。但是在错误的时候&#xff0c;程序就直接返回那么&#xf…

密集书库是什么意思?图书馆密集书库的书可以借出吗

密集书库是一种用于存储大量书籍和资料的高密度储存设施。它通常包括一系列钢制书架和可移动的储存架&#xff0c;使得书籍可以被紧密地排列和存储&#xff0c;以最大程度地利用存储空间。同时&#xff0c;密集书库还有各种自动化系统&#xff0c;如自动化取书系统、气候控制系…

安卓apk抓包(apk抓不到包怎么办)

起因 手机&#xff08;模拟器&#xff09;有时候抓不到apk的包&#xff0c;需要借助Postern设置一个代理&#xff0c;把模拟器的流量代理到物理机的burp上。 解决方案 使用Postern代理&#xff0c;把apk的流量代理到burp。 Postern是一个用于代理和网络流量路由的工具&#xf…

Linux coredump异常处理

什么是coredump异常调试 Linux coredump功能是当Linux下应用程序异常时,Linux内核默认的一种异常信号处理机制,内核会把异常信息与进程内存转储成coredump文件,程序员通过gdb工具可以离线分析应用程序异常时的情况。 1)配置 core 文件生成的目录,其中 %e 表示程序文件名,…

Linux Namespace技术

对应到容器技术&#xff0c;为了隔离不同类型的资源&#xff0c;Linux 内核里面实现了以下几种不同类型的 namespace。 UTS&#xff0c;对应的宏为 CLONE_NEWUTS&#xff0c;表示不同的 namespace 可以配置不同的 hostname。User&#xff0c;对应的宏为 CLONE_NEWUSER&#xf…

骨传导耳机会影响听力么?盘点骨传导耳机的好处与坏处都有哪些?

先说结论&#xff0c;使用骨传导耳机是不会影响听力的&#xff01;并且由于骨传导耳机的特殊传声原理&#xff0c;相比于传统的入耳式耳机&#xff0c;骨传导耳机拥有更多的优点&#xff0c;下面带大家了解一下骨传导耳机的优点和缺点都有哪些。 一、骨传导耳机的优点是什么&a…

kubectl获取ConfigMap导出YAML时如何忽略某些字段

前言&#xff1a; 当我们在使用Kubernetes时&#xff0c;常常需要通过kubectl命令行工具来管理资源。有时我们也想将某个资源的配置导出为YAML文件&#xff0c;这样做有助于版本控制和资源的迁移。然而&#xff0c;默认情况下&#xff0c;使用kubectl get命令导出资源配置会包…

PTA 7-224 sdut-C语言实验-排序问题

输入10个整数&#xff0c;将它们从小到大排序后输出&#xff0c;并给出现在每个元素在原来序列中的位置。 输入格式: 输入数据有一行&#xff0c;包含10个整数&#xff0c;用空格分开。 输出格式: 输出数据有两行&#xff0c;第一行为排序后的序列&#xff0c;第二行为排序…

JVM:双亲委派(未完结)

类加载 定义 一个java文件从编写代码到最终运行&#xff0c;必须要经历编译和类加载的过程&#xff0c;如下图&#xff08;图源自b站视频up主“跟着Mic学架构”&#xff09;。 编译就是把.java文件变成.class文件。类加载就是把.class文件加载到JVM内存中&#xff0c;得到一…