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

MySQL事务管理(上)

目录

前言

CURD不加控制,会有什么问题?

 CURD满足什么属性,能解决上述问题?

 事务

什么是事务?

为什么会出现事务 

 事务的版本支持

 事务提交方式

 查看事务提交方式

改变 MySQL 的自动提交模式:

 事务常见操作方式

前序

 正常演示

 非正常演示

 结论

 事务隔离级别

如何理解隔离性

隔离级别 

隔离级别的影响

查看与设置隔离性 

查看

设置

 读未提交【Read Uncommitted】

读提交【Read Committed】

 可重复读【Repeatable Read】

串行化【serializable】 

总结

 事务的一致性


MySQL注定会被多个用户或者客户端,因为MySQL存的是数据;MySQL内部使用的是多线程的方式来实现数据的存储工作;

前言

CURD不加控制,会有什么问题?

如今有个数据库里面是火车票售票系统所对应的数据库表;MySQL是一个网络服务可以被多人服务那么在抢票的时候任何人都可以抢票,那么多个客户端都在同时读取数据;那么日常生活中转账也是一样了,A现在想给B转账(同行银行卡),那么做法就是把A账上的钱减少200元给B账上加200因为是同行所以用的是同一张数据库的表,在减A这张表数据的时候网络出现问题或者数据库出问题或者其他原因导致在B上没有把数据加上来,那么就有了中间过程,就相当于A说我转了但是B说我没收到。我们允许有异常产生但是要把数据补回来,返回正常;

 CURD满足什么属性,能解决上述问题?

1. 买票的过程得是原子的吧

2. 买票互相应该不能影响吧

3. 买完票应该要永久有效吧

4. 买前和买后都要是确定的状态吧

 事务

什么是事务?

事务就是一组DML语句(允许用户或应用程序从数据库中检索、添加、修改和删除数据,以及执行数据的各种管理任务)成,这些语句在逻辑上(站在上层使用者的角度)存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的(因为到来的时间不同,所以看到不同的数据)。(简单来说事务就是一条或多条sql共同构成的一个sql集合体,这个集合体要共同一起完成某个任务这就叫事务)

事务就是要做的或所做的事情主要用于处理操作量大,复杂度高的数据。假设一种场景:你毕业了, 学校的教务系统后台 MySQL 中,不再需要你的数据,要删除你的所有信息(一般不会) ), 那么要删除你的基本信息(姓名,电话,籍贯等)的同时,也删除和你有关的其他信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条 MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务。(站在程序员角度来讲就是一串delete,这些delete合起封装起来叫事务,严格上来说事务并不是程序员术语,而是站在使用者的上层角度)

正如我们上面所说,一个 MySQL 数据库,可不止你一个事务在运行,同一时刻,甚至有大量的请求被包装成事务,在向 MySQL 服务器发起事务处理请求。每条事务至少一条 SQL ,最多很多 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况,就绝对会出现问题。甚至,因为事务由多条 SQL 构成,那么也会存在执行到一半出错或者不想再执行的情况,那么已经执行的怎么办呢?

所以一个完整的事务绝对不是简单的 sql 集合,还需要满足如下四个属性

原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交( Read uncommitted )、读提交( read committed )、可重复读( repeatable read )和串行化 ( Serializable )

持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。(数据持久化)

 上面四个属性,可以简称为 ACID :原子性(Atomicity,或称不可分割性) 一致性(Consistency) 隔离性(Isolation,又称独立性) 持久性(Durability)。

为什么会出现事务 

MySQL要同时帮我们不同的客户端处理不同的事务请求,决定了MySQL在运行期间有大量的事务,同时也要管理这些事务;

事务不能仅仅站在程序员的角度考虑问题,一定要站在数据库的使用者的角度考虑问题;

事务被 MySQL 编写者设计出来(事务并不是天然就有的),本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型(让上层用的更舒服), 不需要我们去考虑各种各样的潜在错误和并发问题.可以想一下当我们使用事务时,要么提交,要么回滚,我 们不会去考虑网络异常了,服务器宕机了,同时更改一个数据怎么办对吧?因此事务本质上是为了应用层服务的.而不是伴随着数据库系统天生就有的,而是后来设计的,发现问题了就设计出解决问题的方法.

MySQL可以有数据库,数据库里有表,表里面可以有一行信息,我们把这一行信息叫做一行记录;

 事务的版本支持

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

先查看当前MySQL所支持的存储引擎:mysql> show engines\G     有很多个
support为default代表我MySQL当前使用innodb为默认引擎;savepoints表示支持事务保存点



可以看到myisam不支持事务

 事务提交方式

事务的提交方式常见的有两种: 自动提交       手动提交

 查看事务提交方式

mysql> show variables like 'autocommit'; //ON表示自动提交

改变 MySQL 的自动提交模式:

mysql> set autocommit=0;//关掉自动提交

mysql> set autocommit=1;//打开自动提交

 事务常见操作方式

前序

首先我们清楚MySQL是命令行式的客户端,mysqld是服务端

记住MySQL的服务一般不要暴漏在公网上,暴漏在公网上别人也可以连接,我也可以连接但是不一定能登录,因为MySQL不仅需要账号密码还要求在哪里登录;

使用netstat查看链接情况,可知:mysql本质是一个客户端进程

 为了便于演示,我们将mysql的默认隔离级别设置成读未提交。(后续会将隔离级别)

mysql>  set global transaction isolation level read uncommitted;

现在查发现是可重复读


则需要重启客户端重新登陆即可

 现在让两个用户同时连接MySQL,两个客户端访问mysqld服务

创建测试表 mysql> create table if not exists account(
    -> id int primary key,
    -> name varchar(50) not null default '',
    -> blance decimal(10,2) not null default 0.0
    -> )engine=innodb default charset=utf8;

 mysql> show processlist;//查看多少人访问服务

用于实时监视和了解数据库当前的活动连接和执行情况,每一行代表一个连接(也就是一个进程),包括连接的ID、用户、主机、数据库、执行的SQL语句等信息。

 正常演示

-证明事务的开始与回滚

mysql> show variables like 'autocommit';查看事务是否自动提交。我们故意设置成自动提交,看看该选项是否影响begin
启动事务:start  transaction或者begin都可以,两个客户端不同的启动方式,启动2个事务;


创建一个保存点save1:mysql> savepoint save1;//在左边客户端创建
右边客户端查看数据:为什么右边可以看到因为我设置的是读未提交
左边客户端插入数据:mysql> insert into account values (1, '张三', 100);
右边查看数据:发现查到了

再创建一个保存点save2:mysql> savepoint save2;//在左边客户端创建,设置保存点方便未来定向回滚
左边客户端插入数据:insert into account values (2, '李四', 10000);
右边查看数据:发现查到了

下边的所有都属于同一个事物,也就是说这些sql都会被打包成一个事务让我们的mysql执行(begin之后到commit之前都属于同一个事务)
 
当然如果想放弃插入的话可以使用回滚:mysql> rollback to save2;//因为我设置了保存点所以可以定向回滚
再查数据:发现第二条插入没了;回滚到哪个插入点则插入点后面的sql都没有用了
回滚到最开始即不想要这个事务了mysql> rollback;//直接rollback,回滚在最开始

再次进行查找:发现没有数据了
如果不想再进行操作了可以进行commit提交(commit之后代表这个事务结束了)
commit 是用来提交事务的命令,当执行 commit 后,数据库系统会将事务中的所有操作永久性地应用到数据库中。这意味着所有的数据修改、插入、更新或删除操作都会被保存到数据库中,同时释放相关的锁资源,使得其他事务可以访问这些数据。

 重新开始事务:
不设置保存点进行插入:
查找数据:
因为没有设置保存点所以不能定向回滚所以只能回到最开始:mysql> rollback;
再次查找:发现为空,数据全没了
再进行提交:commit

 再次开始新的事务:
左边再次插入:
右边再次查找:
进行保存:mysql> commit;//进行commit之后再进行rollback就没意义了

回滚只有在事务运行期间才有意义
这时候再进行查找:发现数据持久化保存了

 非正常演示

1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交)

 开始事务:begin

查找数据:
插入数据:mysql> insert into account values (3, '王五', 100007);


因为是读未提交所以另一个事务能看到数据:右边的事务查找
不commit,而是左边使用ctrl + \ (异常终止MySQL)后,发现MySQL崩溃退出了,会发现事务自动回滚 这时右边的MySQL还没退出,进行查找数据:发现id=3的数据没有因为没有提交事务

 2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化

 开始事务:
插入数据:mysql> insert into account values (3, '王五', 100007);

查找数据:
进行commit提交再进行查找:发现数据还在
那么我此时再进行异常退出(ctrl+\),我再查找:发现数据还在
甚至我把右边的事务终止掉再进行查找:发现还在
换而言之只要commit了数据就持久化了无论正常退出还是异常退出都没有对数据产生影响


那么我明明设置的是自动提交,但是我刚才为什么异常退出的时候出现回滚了则代表没有提交事务?那是因为我是手动提交,我用了begin或者start  transaction表示我手动提交,跟我设置的没有一点关系;

 3 - 对比试验。证明begin操作会自动更改提交方式,不会受MySQL是否自动提交影响

 查看事务提交方式:mysql> show variables like 'autocommit';
关闭自动提交:mysql> set autocommit=0;//因为这个操作是局部的(退出mysql再进还是ON),所以要在两个客户端同时执行才能都修改;重新登陆后查看还是ON

查看关闭后的:
开始事务:begin


左边插入数据:mysql> insert into account values (4, '赵六', 12369);

右边查找数据:
左边进行异常终止ctrl+\然后在右边进行再进行查找:发现插入的不在了
说明左边终端崩溃后,自动回滚说明不是自动提交


说明手动开始事务就要手动commit跟是否自动没有关系

 4 - 证明单条 SQL 与事务的关系

我们以前从来都是单sql外加其他操作,我们没有写过begin和commit;

关闭自动提交:
我不begin了而是插入数据:mysql> insert into account values (4, '赵六', 12369);
查找:
ctrl + \ or ctrl + d,终止左边终端,在右边进行查找:发现赵六没有了

 开启自动提交:


进行插入:mysql> insert into account values (4, '赵六', 12369);
右边终端查找:
ctrl + \ or ctrl + d,终止左边终端,再在右边进行查找:发现数据保存了不跟上次一样
左边终端崩溃后,并不影响,已经持久化。autocommit 起作用;单sql对于autocommit来说就是事务

 结论

1. 只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是 否设置set autocommit无关。

2. 事务可以手动回滚,同时,当操作异常,MySQL会自动回滚

3. 对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为 MySQL 有 MVCC )

4. 从上面的例子,我们能看到事务本身的原子性(回滚),持久性(commit)

 事务操作注意事项

1. 如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)

2. 如果一个事务被提交了(commit),则不可以回退(rollback)

3. 可以选择回退到哪个保存点

4. InnoDB 支持事务, MyISAM 不支持事务

5. 开始事务可以使 start transaction 或者 begin

 事务隔离级别

如何理解隔离性

MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行;

一个事务可能由多条SQL构成,也就意味着,任何一个事务,都有执行前执行中执行后的阶 段。而所谓的原子性,其实就是让用户层,要么看到执行前,要么看到执行后执行中出现问题, 可以随时回滚。所以单个事务,对用户表现出来的特性,就是原子性。

但毕竟所有事务都要有个执行过程,那么在多个事务各自执行多个SQL的时候,就还是有可能会 出现互相影响的情况。比如:多个事务同时访问同一张表,甚至同一行数据。

就如同你妈妈给你说:你要么别学,要学就学到最好。至于你怎么学,中间有什么困难,你妈妈不 关心。那么你的学习,对你妈妈来讲,就是原子的。那么你学习过程中,很容易受别人干扰,此 时,就需要将你的学习隔离开,保证你的学习环境是健康的。

数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性;

数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别;

在事务场景中隔离是必须的 ,这个隔离是运行中的事务进行隔离(运行前和运行后不管);

隔离级别 

读未提交【Read Uncommitted】:

这是最低的隔离级别,在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。

读提交【Read Committed】 :

该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果。 

 可重复读【Repeatable Read】:

这是 MySQL 默认的隔离级别,这个级别确保一个事务在执行期间多次读取相同数据时,看到的数据保持一致,会看到同样的数据行,即使其他事务修改了这些数据也不会影响当前事务。

可以避免脏读和不可重复读的问题,但仍可能出现幻读问题(即在同一事务中多次查询时,结果集中的行数不一致)

 串行化【Serializable】:

这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突, 从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争 (这种隔离级别太极端,实际生产基本不使用)

隔离级别如何实现:隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见有,表 锁,行锁,读锁,写锁,间隙锁(GAP),Next-Key锁(GAP+行锁)等。不过,我们目前现有这个认识就行, 先关注上层使用。 

隔离级别的影响

  • 隔离级别越低,例如读未提交,数据库的并发控制越少,因为事务可以相互干扰并看到彼此未提交的工作。
  • 而隔离级别越高,如可重复读或串行化,数据库会更加严格地控制事务的并发执行,以确保数据的一致性和隔离性

查看与设置隔离性 

查看

在MySQL当中有三种查看隔离级别方法:

mysql> SELECT @@global.tx_isolation;//查看全局隔级别 

 mysql> SELECT @@session.tx_isolation;//查看会话(当前)全局隔级别

 mysql> SELECT @@tx_isolation;//是@@session.tx_isolation的简写,效果是一样的

global与 session的区别就是global是session的默认配置,当我们在登陆MySQL的时候,默认MySQL会读取全局配置好的隔离级别,用来初始化本次登陆的会话隔离级别;这就有点像我global设置好了相当于全局的配置,我们的session默认选择把global的拷贝一份给自己当然也可以更改这个隔离级别(更改session的话只会影响当前会话的隔离级别,更改global的话影响后续所有的客户端登录);
会话可以理解为客户端与服务端进行持续交互过程,一个数据库会话从客户端应用程序连接到数据库开始,到断开连接结束,期间可以执行多个SQL查询和事务操作;在数据库管理系统中,一个会话(session)从客户端应用程序连接到数据库开始,直到断开连接结束,这段时间内的所有交互和操作都属于同一个会话。在这个会话期间,客户端可以执行多个SQL查询和事务操作,这些操作可以涉及数据的读取、写入、更新和删除等。

设置

语法:set [session | global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable}//建议不要省略[]里的内容

设置当前会话隔离性:mysql> set session transaction isolation level read committed;

查看当前会话隔离级别:mysql> SELECT @@session.tx_isolation;查看全局隔离级别:mysql> SELECT @@global.tx_isolation;//没受影响

另起一个客户端查看全局隔离级别:mysql> SELECT @@global.tx_isolation;//不受影响 查看当前会话的隔离级别:mysql> SELECT @@session.tx_isolation;//是global的拷贝

那么现在右边终端的隔离级别三位一体都是读未提交,左边的隔离级别有读未提交和读提交那么左边用哪个,MySQL会采用就近原则使用session的隔离级别;

更改全局隔离级别:mysql> set global transaction isolation level serializable;

查看左边全局隔离级别:mysql> SELECT @@global.tx_isolation;
查看左边当前会话隔离级别:mysql> SELECT @@session.tx_isolation;

查看右边全局隔离级别:mysql> SELECT @@global.tx_isolation;


查看右边当前会话隔离级别:mysql> SELECT @@session.tx_isolation;
发现更改全局后只有全局变了而左右端口的当前会话没有变,只有重新登陆才会发生变化;

如果想恢复默认数据库隔离级别可以自己设置或者重启MySQL服务restart(不是重新登录) 

 读未提交【Read Uncommitted】

几乎没有加锁,虽然效率高,但是问题太多,严重不建议采用

设置隔离级别为读未提交:mysql> set global transaction isolation level read uncommitted;

重启客户端查看当前会话隔离级别:mysql> SELECT @@session.tx_isolation;

让两个客户端同时begin那么就是并发在跑 ;左边客户端对数据修改操作未提交,右边的客户端可以立即看到修改后的;可以读到别人未提交的数据因为我没加锁,但是事务roolback的话数据就没了;

 一个事务在执行中,读到另一个执行中事务的更新(或其他操作)但是未commit的数据,这种现象叫做脏读 (dirty read),这是一种不和理的现象(并发的过程);

读提交【Read Committed】

设置全局变量:set global transaction isolation level read committed;

重启客户端查看级别:两个客户端都是一样的都是读提交

启动事务:begin
右边查找数据:
左边插入数据未提交:mysql> insert into account values (6, '赵七', 123666);
右边再进行查找:发现没有新插入的(但那时数据已经被写入到数据库中了)
但是左边的表自己查数据发现能查到新插入的数据:自己事物内部随便
左边的commit之后右边再查发现能查到新的数据:右边的事务没有结束,能查到结束的事务,查不到运行中的事务;

但是我右边的事务还在运行前后查到的数据不同,此时还在当前事务中,并未commit,那么就造成了,同一个事务内,同样的读取,在不同的时间段 (依旧还在事务操作中!),读取到了不同的值,这种现象叫做不可重复读(non reapeatable read)!!

我提交了是应该让其他事务看到但不应该让运行中的事务(并发运行中的)看到, 可以让后续的新起的事务看到;

不可重复读会导致:

  1. 数据不一致性:由于两次读取同一行数据的结果不同,事务内部的处理逻辑可能会基于错误的数据状态进行操作,导致最终的数据结果与预期不符。

  2. 难以复现问题:由于不可重复读问题通常是由并发事务导致的,而且不易稳定复现,这使得排查和解决问题变得更加复杂和耗时。

  3. 逻辑错误和处理异常:在某些场景下,事务处理可能依赖于读取到的数据的稳定性和一致性。如果出现了不可重复读,可能会导致程序逻辑错误或者异常情况的发生,影响应用程序的正常运行。

  4. 事务处理安全性降低:不可重复读问题会降低事务的隔离性,从而增加了处理并发访问时出现异常情况的风险。这可能需要通过选择更高的事务隔离级别或者调整业务逻辑来弥补。

 可重复读【Repeatable Read】

设置全局变量:set global transaction isolation level repeatable read;

重新登陆MySQL查看当前会话隔离级别:两个客户端都改变了

并发启动: begin


右边查看当前表数据:
左边事务进行更新数据操作:mysql> update account set name='lisi' where id=2;

左边事务自己查看数据:发现更新了

右边事务查看数据:发现数据没更新
左边事务commit后右边事务查看数据:发现还是没变化
也即是说运行中的事务不会受到并发运行中的事务的影响即使其他并发事务commit了;只有commit了才能看到更新的数据;我不是不让你看而是不能让运行中的事务看到

右边事务commit,右边再查看数据:发现数据更新了

多次查看,发现终端A在对应事务中insert或者update的数据,在终端B的事务周期中也没有什么影响,也符合可重复的特点。但是,一般的数据库在可重复读情况的时候,无法屏蔽其他事务insert的数据(为什么?因为隔离性实现是对数据加锁完成的,而insert待插入的数据因为并不存在,那么一般加锁无法屏蔽这类问题),会造成虽然大部分内容是可重复读的,但是insert的数据在可重复读 情况被读取出来,导致多次查找时,会多查找出来新的记录,就如同产生了幻觉。这种现象,叫做幻读 (phantom read)。很明显,MySQL在RR级别的时候,是解决了幻读问题的(解决的方式是用Next-Key锁 (GAP+行锁)解决的)。幻读是专门针对于insert,也是不可重复读的一种;

串行化【serializable】 

对所有操作全部加锁,进行串行化,不会有问题,但是只要串行化,效率很低,几乎完全不会被采用;它确保事务之间完全串行执行,也就是说每个事务只能依次执行(注定了事务按照到来的顺序排队),一个事务执行完毕后另一个事务才能开始执行。这种级别提供了最高的数据一致性和隔离性,确保事务之间不会相互干扰或者产生任何并发问题,如脏读、不可重复读和幻读。

设置全局隔离级别:set global transaction isolation level serializable;

重新登陆:发现两个终端当前会话隔离级别改变了

 启动事务:
查找数据:两个读取不会串行化,共享锁
我左边事务进行删除操作:发现卡住了
右边进行查询:多次查询还能查到
右边进行提交:一提交左边事务就立马完成删除操作了


终端A中有更新或者其他操作(读select不会受到阻塞),会阻塞,直到终端B事务提交

 再次重新启动事务,左边删除操作时堵塞了,只有右边commit了才能左边才不堵塞,堵塞的同时右边可以进行任何操作:
右边在左边进行的堵塞的时候查找到右边修改的数据:

堵塞的时间过长会导致事务自动结束,这是只有重新启动事务:

commit了不堵塞了:

但是我在右边重新查找:发现id=2的数据没被删除,这是因为我左边的事务还未被commit
都commit再查找:看到数据被删除了


当A和B都串行化时,select共用锁直接访问数据,但是增删改操作时会被放到MySQL的等待队列,当事务commit了才能进行后续操作

总结

其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平 衡点。(这个平衡点不是MySQL决定的而是根据场景根据用户的使用)

不可重复读的重点是修改和删除:同样的条件, 你读取过的数据,再次读取出来发现值不一样了 幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样

说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改

上面的例子可以看出,事务也有长短事务这样的概念。事务间互相影响,指的是事务在并行执行的 时候,即都没有commit的时候,影响会比较大。

 事务的一致性

事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务 成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中 断,而该未完成的事务对数据库所做的修改已被写入数据库,此时数据库就处于一种不正确(不一 致)的状态。因此一致性是通过原子性来保证的。

其实一致性和用户的业务逻辑强相关,一般MySQL提供技术支持,但是一致性还是要用户业务逻辑做支撑,也就是,一致性是由用户决定的

而技术上,通过AID保证C(一致性是果,通过原子性,隔离性,持久性来维持一致性),严格来说一致性是要由数据库和程序员一起来维护的

由于本人实力有限,推荐大家可以了解更多的文章:

https://www.jianshu.com/p/398d788e1083

https://tech.meituan.com/2014/08/20/innodb-lock.html https://www.cnblogs.com/aspirant/p/9177978.html

后续操作如何理解隔离性2 (将更加了解隔离性的原理,使大家不迷惑)有机会了写文章,期待大家的点评;

相关文章:

MySQL事务管理(上)

目录 前言 CURD不加控制,会有什么问题? CURD满足什么属性,能解决上述问题? 事务 什么是事务? 为什么会出现事务 事务的版本支持 事务提交方式 查看事务提交方式 改变 MySQL 的自动提交模式: 事务常见操作方式 前…...

HTML2048小游戏

源代码在效果图后面 效果图 源代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2048 Game&l…...

为 android编译 luajit库、 交叉编译

时间&#xff1a;20200719 本机环境&#xff1a;iMac2017 macOS11.4 参考: 官方的文档&#xff1a;Use the NDK with other build systems 写在前边&#xff1a;交叉编译跟普通编译类似&#xff0c;无非是利用特殊的编译器、链接器生成动态或静态库; make 本质上是按照 Make…...

【音视频】音频重采样

文章目录 前言音频重采样的基本概念音频重采样的原因1. 设备兼容性2. 文件大小和带宽3. 音质优化4. 标准化和规范5. 多媒体同步6. 降低处理负载重采样的注意事项 总结 前言 音频重采样是指将音频文件的采样率转换成另一种采样率的过程。这在音频处理和传输中是一个常见且重要的…...

卷积神经网络学习问题总结

问题一&#xff1a; 深度学习中的损失函数和应用场景 回归任务&#xff1a; 均方误差函数&#xff08;MSE&#xff09;适用于回归任务&#xff0c;如预测房价、预测股票价格等。 import torch.nn as nn loss_fn nn.MSELoss() 分类任务&#xff1a; 交叉熵损失函数&…...

嵌入式面试总结

C语言中struct和union的区别 struct和union都是常见的复合结构。 结构体和联合体虽然都是由多个不同的数据类型成员组成的&#xff0c;但不同之处在于联合体中所有成员共用一块地址空间&#xff0c;即联合体只存放了一个被选中的成员&#xff0c;结构体中所有成员占用空间是累…...

超简单安装指定版本的clickhouse

超简单安装指定版本的clickhouse 命令执行shell脚本 idea连接 命令执行 参考官网 # 下载脚本 wget https://raw.githubusercontent.com/183461750/doc-record/d988dced891d70b23c153a3bbfecee67902a3757/middleware/data/clickhouse/clickhouse-install.sh # 执行安装脚本(中…...

FlowUs横向对比几款笔记应用的优势所在

FlowUs作为一个本土化的生产力工具&#xff0c;在中国市场的环境下相对于Notion有其独特的优势&#xff0c;尤其是在稳定性和模板适应性方面。 尽管Notion在笔记和生产力工具领域享有极高的声誉&#xff0c;拥有着诸多创新功能和强大的生态系统&#xff0c;但它并不一定适合每…...

收银系统源码-千呼新零售收银视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…...

从Catalog说到拜义父-《分析模式》漫谈11

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的Preface&#xff08;前言&#xff09;有这么一句&#xff1a; This book is thus a catalog, rather than a book to be read from cover to cover. 2004&am…...

Qt判定鼠标是否在该多边形的线条上

要判断鼠标是否在由QPainterPath或一系列QPointF点定义的多边形的线条上&#xff0c;你可以使用以下步骤&#xff1a; 获取鼠标当前位置&#xff1a;在鼠标事件中&#xff0c;使用QMouseEvent的pos()方法获取鼠标的当前位置。 检查点与线段的距离&#xff1a;遍历多边形的每条…...

【笔记:3D航路规划算法】一、随机搜索锚点(python实现,讲解思路)

目录 关键概念3D路径规划算法1. A*算法2. 快速随机锚点1. 初始化&#xff1a;2. 实例化搜索算法&#xff1a;3. 路径生成&#xff1a;4. 绘制图像&#xff1a; 3D路径规划是在三维空间中寻找从起点到终点的最短或最优路径的一种技术。它广泛应用于无人机导航、机器人运动规划、…...

ubuntu如何彻底卸载android studio?

最新版的ubuntu已经使用snap进行软件管理了&#xff0c;我用snap-store安装android studio以后&#xff0c;在安装plugin的时候强制退出后&#xff0c;直接再也进不去了&#xff0c;启动就报错。 先后进行了如下操作依然不行&#xff1a; 1 重装snap-store和android studio都…...

使用Windows Linux 子系统安装 Tensorflow,并使用GPU环境

在Microsoft Store商店安装Ubuntu 20.04 使用 nvidia-smi 命令查看GPU信息&#xff0c;查看支持的CUDA版本&#xff0c;这里最高支持11.7 安装cuda工具集 进入官网&#xff1a;CUDA Toolkit Archive | NVIDIA Developer&#xff0c;现在对应版本&#xff0c;点击 配置平台&…...

C++案例三:猜数字游戏

文章目录 介绍代码说明设置随机种子生成随机数猜测循环完整代码运行效果介绍 猜数字游戏是一个经典的编程练习,通过这个案例可以学习到基本的输入输出、随机数生成、条件判断和循环结构。 代码说明 设置随机种子 std::srand(static_cast<unsigned int>(std::time(nu…...

LNMP架构部署及应用

部署LNMP架构流程 1.安装Nginx&#xff08;上传软件包&#xff0c;执行脚本&#xff09; yum -y install pcre-devel zlib-devel gcc gcc useradd -M -s /sbin/nologin nginx tar zxf nginx-1.12.0.tar.gz cd nginx-1.12.0 ./configure --prefix/usr/local/nginx --usernginx…...

【医学影像】X86+FPGA:支持AI医学影像设备应用的工控主板,赋能CT、MRI、X线、超声等医学影像设备

支持AI医学影像设备应用的工控主板 在我国人口老龄化问题不断加剧&#xff0c;对影像诊断需求持续增长&#xff0c;和国家利好高端医学影像市场发展的系列法规和政策接连出台的大环境下&#xff0c;AI医学影像设备产业迎来发展黄金期。紧跟发展大势&#xff0c;基于12/13代 In…...

【PostgreSQL】PostgreSQL简史

博主介绍&#xff1a;✌全网粉丝20W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

Linux的热插拔UDEV机制和守护进程

目录 一、Linux的热插拔UDEV机制 二、守护进程 2.1 守护进程概念和基本特点&#xff1a; 2.2 显示进程信息&#xff1a; 2.3 守护进程和后台进程的区别&#xff1a; 2.4 创建守护进程的步骤和守护进程的特征&#xff1a; 2.4.1 创建守护进程的步骤&#xff1a; 2.4.2 守…...

laravel框架基础通识-新手

常用目录及其解析 routes 该目录为路由目录 一般根据api uri可以反向查找对应路由及其controller&#xff0c;目录下的文件名一般和url的第一级对应为了规范&#xff0c;然后根据根据里面具体分组和别名对应拼接对应路由url&#xff0c;后面对应的则是controller&#xff0c…...

c++ extern 关键字

C中的extern关键字和跨语言互操作 变量的声明与定义 extern关键字用于声明在另一个翻译单元&#xff08;文件&#xff09;中定义的变量或函数。通过extern关键字&#xff0c;可以在多个文件中访问全局变量或函数。 变量声明示例 文件&#xff1a;main.cpp #include <io…...

Meta KDD Cup 2024 CRAG: Comphrehensive RAG Benchmark参赛指南(写了一半跑去改大论文了所以没正式参赛)

诸神缄默不语-个人CSDN博文目录 因为比赛过程正好和我毕业答辩的时间段高度重合&#xff0c;所以我……最后其实还是相当于没有成功参赛。 呃反正现在已经咕咕咕了&#xff0c;就把当时写了一半&#xff08;一小半&#xff09;的参赛指南发一下吧。 官网&#xff1a;AIcrowd …...

系统架构设计师教程 第3章 信息系统基础知识-3.7 企业资源规划(ERP)-解读

系统架构设计师教程 第3章 信息系统基础知识-3.7 企业资源规划&#xff08;ERP&#xff09; 3.7.1 企业资源规划的概念3.7.2 企业资源规划的结构3.7.2.1 生产预测3.7.2.2 销售管理&#xff08;计划&#xff09;3.7.2.3 经营计划&#xff08;生产计划大纲&#xff09;3.7.2.4 …...

windows实现自动化按键

1.选择目标窗口 获取窗口句柄 void KeyPresser::selectWindow() {SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);selectedWindowLabel->setText("请点击目标窗口..."); }void CALLBACK …...

阿里云 https证书部署

一.申请证书 二.查看状态 查看状态&#xff0c;已签发是完成了申请证书 三.部署 我在nginx服务器上部署 具体操作链接:阿里云文档 修改前 修改后 四.重启ngnix 五.验证是否成功 在浏览器输入域名查看...

DX-10A信号继电器 柜内安装,板前接线 约瑟JOSEF

DX-10型闪光信号继电器型号&#xff1a; DX-10A闪光信号继电器&#xff1b; DX-10B闪光信号继电器&#xff1b; DX-10C闪光信号继电器; 用途 DX-10 闪光继电器用于电力系统断路器的位置信号灯不对应闪光&#xff0c;该继电器是为了适应当前推广使用发光二极管节能指示灯而…...

芯片光刻后的晶片多层组合构成的吗

是的&#xff0c;芯片&#xff08;尤其是集成电路芯片&#xff09;确实是通过光刻后的晶片多层组合构成的。在芯片制造过程中&#xff0c;光刻是一个至关重要的步骤&#xff0c;用于在硅片&#xff08;或称为晶片&#xff09;上刻画出精确的电路图案。然而&#xff0c;一个完整…...

OpenGL-ES 学习(7) ---- VBO EBO 和 VAO

目录 VBO(Vertex Buffer Object)EBO(Element Buffer Object)VAO(Vertex Array Object) VBO(Vertex Buffer Object) EBO(Element Buffer Object) VBO(Vertex Buffer Object) 实际是指顶点缓冲器对象 在 opengl-es 2.0 的编程中&#xff0c;用于绘制图元的顶点数据是从 CPU 传…...

github如何实现和gitlab的同步

要实现 GitHub 和 GitLab 之间的同步&#xff0c;你可以使用以下几种方法。这里介绍两种常用的方法&#xff1a;使用 GitLab CI/CD 和使用镜像仓库。 方法1&#xff1a;使用 GitLab CI/CD 通过 GitLab CI/CD&#xff0c;可以在每次推送到 GitLab 时自动同步到 GitHub。以下是…...

内网隧道——隧道技术基础

文章目录 一、正向连接与反向连接1.1 正向连接1.2 反向连接 二、端口转发三、端口映射四、端口复用五、代理和隧道的区别六、常见隧道穿透分类 环境&#xff1a; kali&#xff1a;192.168.92.6&#xff0c;MSF v6.3.25 win7&#xff1a;192.168.92.7 一、正向连接与反向连接 1…...

做视频解析网站违法不/优化大师 win10下载

示例1&#xff1a; 输入 5 1000000007 2 3 4 5 107输出 2 24 264 3240 736935633题意&#xff1a; 一个森林的代价为内部每个节点度数的平方和。问所有带标号的n 个点的森林的代价和 。 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 5…...

wordpress 页面 微博/网络优化大师

一、为什么会出现SpringCloud Alibaba 《SpringCloud 日志》中&#xff0c;有一段新闻信息描述&#xff1a; 详情参考&#xff1a;《Spring Cloud Netflix项目进入维护模式》 二、简介 具体查看&#xff1a;《官方 github readme 描述》 三、总结 使用SpringCloud Alibab…...

企业网站营销的成功案例/有没有专门做营销的公司

如题。 之前是IE7时正常&#xff0c;装IE8后在VS2005中按F5正常启动&#xff0c;但是打开IE之后VS2005自动回到非调试状态。 在调试菜单中“附加到进程”中附加到WebDev.WebServer.EXE倒是可以&#xff0c;不知道是怎么回事。 转载于:https://www.cnblogs.com/chinhr/archive/2…...

辽宁工程建设信息网站/识图搜索在线 照片识别

独享还是共享&#xff0c;你选择哪一种锁 前言 今天博主将为大家分享独享还是共享&#xff0c;你选择哪一种锁&#xff1f;&#xff08;独享锁/共享锁&#xff09;&#xff0c;不喜勿喷&#xff0c;如有异议欢迎讨论&#xff01; 有一个强大的地基才能写出健壮的程序&#xf…...

商务网站模块设计时前台基础设施建设/百度应用商店app

1007. 素数对猜想 (20) 时间限制400 ms内存限制32000 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue让我们定义 dn 为&#xff1a;dn pn1 - pn&#xff0c;其中 pi 是第i个素数。显然有 d11 且对于n>1有 dn 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素…...

网站建设20推广/最新军事新闻 今日 最新消息

随机数的不重复选择就是从n个数中随机选取m(m<n)个数。在本文中&#xff0c;我们用Java来实现。因此我们先介绍Java的相关知识。 在Java中&#xff0c;Java.util.Set接口和Java.util.List接口一样&#xff0c;都是继承自Java.util.Collection接口。但是两者有不同的特点&am…...