数据库事务

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

目录

一.事务

1.为什么要存在事务

2.什么是事务

3.事务的特性(ACID)

4.MySQL中事务的使用

二.事务的隔离级别

1.什么是隔离级别

2.隔离级别的分类

3.不同隔离级别的现象

4.MySQL中设置隔离级别

5. 四种隔离级别和锁

1.READ-UNCOMMITED

2.READ-COMMITED

3.REPEATABLE-READ

4.SERIALIZABLE


一.事务

1.为什么要存在事务

刚开始我们拿一个常见的操作来说明我们为什么需要事务.假如现在张三给李四转账100元,我们需要先把张三账户的钱减少100,然后再把李四账户的钱增加100.但是如果张三账户的钱减少100的时候突然发生网络异常,那么张三减少了100,但是李四却没有增加100,这个时候就会出现问题了.

update accout set money=money-100 where name='张三'

update accout set money=money+100 where name='李四'

为了避免这种问题的发生,因此出现了事务(transaction)

2.什么是事务

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败
就比如我们上面的转账的例子,当没有出现网络异常的时候,我们两条语句都执行成功,这个事务就成功执行写入到数据库了(commit),当出现了网络异常的时候,第一条语句成功执行,但是第二条语句没有成功执行,那么第一条语句的数据不会写入到数据库(rollback).

3.事务的特性(ACID)

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

  2. 一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态

  3. 隔离性(Isolation) 事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。(具体见事务的隔离级别)

  4. 持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

4.MySQL中事务的使用

我们可以通过start transaction来开启事务 通过rollback来回滚数据,通过commit来提交数据

案例:对于这样一张accout表数据库事务

1.发生错误rollback数据的情况;

start transaction;
update accout set money=money-100 where name='张三'
#发生网络错误
rollback; 

表中数据未发生改变 数据库事务

2.未发生错误commit数据

start transaction;
update accout set money=money-100 where name='张三';
update accout set money=money+100 where name='李四';
commit;

表中数据发生改变:数据库事务

之前我们都进行过修改,添加和删除操作,这些语句都直接修改了表中的数据.那么大胆推测以下,每一条语句都是一个事务,执行完这一条语句都自动提交到了数据库中.

事实就是如此,我们可以通过以下语句来验证我们的推测.

show variables like '%commit%';

数据库事务

 我们可以看到autocommit=on.

我们可以通过以下语句来设置不自动提交(不推荐)

set autocommit = 0;  #0-->OFF  1-->ON

二.事务的隔离级别

1.什么是隔离级别

MySQL是以服务的形式发布到网络上的,如果有多个用户对一个表进行操作,那么他们之前的操作可能会发生相互影响的情况.

隔离级别:隔离级别是数据库中用于控制并发访问数据一致性的一种机制。当多个事务同时访问数据库时,会出现一些并发问题,如脏读、不可重复读和幻读。隔离级别定义了一个事务对于另一个事务所做的修改的可见性和影响范围,从而保证数据的一致性和正确性。

2.隔离级别的分类

这张表具象的描述了四种隔离级别的描述

数据库事务

 这张表表明了四种隔离级别可能出现的问题和解决的问题

数据库事务

这四种隔离级别从上到下的安全性越来越好,但是性能越来越差

3.不同隔离级别的现象

  • 脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的。

  • 不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。

  • 幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行。之后, 如果 T1 再次读取同一个表, 就会多出几行。

4.MySQL中设置隔离级别

查看MySQL中默认的隔离级别

select @@tx_isolation;

#或者

show variables like 'tx_isolation';

修改默认的隔离级别

set @@global.tx_isolation = '隔离级别' ; // 全局
set @@session.tx_isolation = '隔离级别' ; // 当前 session
set @@tx_isolation = '隔离级别' ;// 仅对下⼀个事务生效

 案例:修改隔离级别为READ-UNCOMMITTED

set @@global.tx_isolation = 'READ-UNCOMMITTED' ; // 全局
set @@session.tx_isolation = 'READ-UNCOMMITTED' ; // 当前 session
set @@tx_isolation = 'READ-UNCOMMITTED' ;// 仅对下⼀个事务生效

注意:设置了全局的隔离级别之后,需要重启客户端之后才能生效

5. 四种隔离级别和锁

先来建立一个user表

create table user(
id int,
name varchar(20)
);

数据库事务

1.READ-UNCOMMITED

这种情况下用户读到了没有被commit的数据,接来下我们测试read-uncommited隔离级别下可能发生的情况.

我们先把MySQL的隔离级别设置为READ-UNCOMMITED

set @@global.tx_isolation = 'READ-UNCOMMITTED';

#重启客户端之后再来查询隔离级别,否则不生效
show variables like 'tx_isolation';

数据库事务显示这样表示修改成功.

接下来我们打开两个客户端(终端) 

初始状态客户端一和客户端二都只含有四条数据.

数据库事务

我们在客户端一开启事务,并且向表中添加一条数据.

START TRANSACTION;

INSERT INTO USER(id,NAME) VALUES(5,'czj');

SELECT * FROM USER;

数据库事务 此时客户端表中的数据为左图所示

我们在客户端二查询数据,发现数据和表一种的数据一模一样.

数据库事务

此时我们在客户端一rollback操作,查询数据

数据库事务此时数据为这样

然后我们在客户端二在进行查询操作

数据库事务数据也变成了这样

客户端二读取到了客户端一还没有commit的数据,这种情况称之为脏读,因为客户端一可能进行rollback操作,所以客户端二读到的没有commit的数据是无效的,因此这种情况使我们一定要避免产生的.

流程图:

数据库事务

 案例:这就相当于作者在CSDN中发表了一篇文章,读者读取到了这一篇文章,但是这个时候作者对这篇文章进行了修改(还没有提交),读者刷新一下,发现了修改的内容,但是作者发现修改不好,就放弃了修改(相当于rollback),读者又刷新了一下,发现修改的内容又恢复了原样.

2.READ-COMMITED

针对READ-UNCOMMITED出现的问题,READ-COMMITED这种隔离级别可以很好的解决.

首先我们将数据库的隔离级别设置为READ-COMMITTED

set @@global.tx_isolation = 'READ-COMMITTED';

#重启客户端之后再来查询隔离级别,否则不生效
show variables like 'tx_isolation';

当出现这种情况的时候表示隔离级别设置成功

数据库事务

我们同样执行上面的操作,发现没有commit之前客户端二的数据都是数据库事务这样就成功的解决了脏读的问题.

READ-COMMITED到底是如何解决脏读的问题呢,其实在这种隔离级别下,我们在事务中加入了一把读锁,这个时候从其他的客户端是无法读取到这个客户端事务中的内容的,只能读取到事务开启之前的内容,当rollback/commit操作的时候,这个时候读锁解除.

数据库事务

 但是这种隔离级别下也会出现问题,下面我们来模拟

我们在客户端一中开启事务查询用户信息

START TRANSACTION;
SELECT * FROM USER;

 数据库事务查询到的数据如图

这个时候我们在客户端二也开启一个事务,修改数据,并且将commit操作

 START TRANSACTION;
UPDATE USER SET NAME='xcl' WHERE id=4;
COMMIT;
SELECT * FROM USER;

数据库事务客户端二的数据如图.

此时我们在客户端一(事务还没有结束)查询user的信息

SELECT * FROM USER;

 数据库事务客户端一的数据如图

以上所描述的类型就是不可重复读

以上操作的流程图

数据库事务

但是事务的原子性的特性,一个事务中的数据是一个整体,怎么可能一个事务中查询到数据不同呢.

案例:这就相当于作者在CSDN中发表了一篇文章,读者读取到了这一篇文章,但是这个时候作者对这篇文章进行了修改,并且进行了提交,读者刷新一下,就发现了修改的内容.

3.REPEATABLE-READ

针对READ-COMMITED出现的问题,REPEATABLE-READ这种隔离级别可以很好的解决.

首先我们将数据库的隔离级别设置为REPEATABLE-READ

SET @@global.tx_isolation = 'REPEATABLE-READ';

#重启客户端之后再来查询隔离级别,否则不生效

SHOW VARIABLES LIKE 'tx_isolation';

数据库事务出现这种情况表示设置成功

 我们同样执行以上的操作,发现

数据库事务在客户端一的事务没有结束之前,查询到的数据都为左表所示

REPEATABLE-READ这种隔离级别通过给事务加上读锁,这样客户端一种查询只能查询到开启事务时的数据(也就是加锁的时候),之后改变的数据无法进入到读锁开启到结束的这段时间(也就是这段事务的期间),因此这期间内读到的数据都是一样的,这样成功解决了不可重复读的问题.

数据库事务

MySQL数据事务的默认隔离级别虽然是可重复读,但是最⼤限度的解决了幻读问题,但是并没有完全解 决,有些场景还是会出现幻读现象,这个大家心里⼀个认识,如果要彻底解决幻读问题,那么只能 事务的隔离级别设置成SERIALIZABLE,也就是串行化.
在目前的版本中测试不出来幻读的问题,我们只需要知道幻读是结果集不一样了就行了
刚开始我们在客户端一开启事务并查询所有用户信息:

START TRANSACTION;

SELECT * FROM USER;

数据库事务    客户端一显示这些信息

客户端二:

SELECT * FROM USER;

START TRANSACTION;

INSERT INTO USER(id,NAME) VALUE(5,'xcl');

COMMIT;

SELECT * FROM USER;

数据库事务   客户端二显示这些信息

然后再从客户端一查询信息(此时客户端一的事务还没有结束)

数据库事务  客户端一显示这些信息

 当客户端一执行commit操作(事务结束),然后查询

数据库事务

没有出现幻读现象,说明REPEATABLE-READ已经解决了一部分的幻读问题,MySQL默认的隔离等级为REPEATABLE-READ已经很合理了.

对于update还是没有解决,此时采用update操作

之前采用select进行查询的时候,是不会出现新增加的数据的

update user set name='zyf' where id=5;

然后再次执行select操作,此时新增加的数据就能被查询到

4.SERIALIZABLE

针对REPEATABLE-READ出现的问题,SERIALIZABLE这种隔离级别可以很好的解决.

我们将数据库的隔离级别设置为SERIALIZABLE

SET @@global.tx_isolation = 'SERIALIZABLE';

#重启客户端之后再来查询隔离级别,否则不生效

SHOW VARIABLES LIKE 'tx_isolation';

数据库事务

 这样可以彻底解决幻读问题.文章来源地址https://www.toymoban.com/news/detail-431619.html

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

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

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

相关文章

  • 什么是 Java 中的数据库连接池?为什么使用连接池来管理数据库连接?

    数据库连接池(database connection pool)是在 Java 中用于管理数据库连接的一种技术。它的主要目的是提高数据库连接的重用性和性能。在传统的数据库连接方式中,每次与数据库建立连接时都需要进行一系列的网络通信和身份验证操作,这样的开销较大并且会影响应用程序的性

    2024年02月06日
    浏览(63)
  • Elasticsearch:什么是向量和向量存储数据库,我们为什么关心?

    Elasticsearch 从 7.3 版本开始支持向量搜索。从 8.0 开始支持带有 HNSW 的 ANN 向量搜索。目前 Elasticsearch 已经是全球下载量最多的向量数据库。它允许使用密集向量和向量比较来搜索文档。 向量搜索在人工智能和机器学习领域有许多重要的应用。 有效存储和检索向量的数据库对于

    2024年02月08日
    浏览(53)
  • 为什么说PostgreSQL是面向对象的数据库?

    PostgreSQL 官方宣称它是世界上最先进的开源对象-关系型数据库管理系统(ORDBMS)。相信大家对于关系型数据库并不陌生,它基于关系模型(由行和列组成的二维表),定义了完整性约束并且使用 SQL 作为操作语言。 不过今天我们的主题不是关系模型,而是 PostgreSQL 提供的面向

    2024年03月25日
    浏览(73)
  • 为什么数据库要允许没有主键的表存在

    在数据库设计中,主键是一个关键概念,用于唯一标识数据库表中的每一行数据。然而,有时候数据库允许没有主键的表存在的情况,这可能会引起一些争议和疑问。本文将探讨为什么数据库允许没有主键的表以及相关的考虑因素。 主键在数据库中具有以下作用: 唯一标识

    2024年02月08日
    浏览(69)
  • mysql面试题30:什么是数据库连接池、应用程序和数据库建立连接的过程、为什么需要数据库连接池、你知道哪些数据库连接池

    该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 数据库连接池是一种用于管理和复用数据库连接的技术。它是在应用程序和数据库之间建立一组数据库连接,并以池的形式存储起来,每当应用程序需

    2024年02月07日
    浏览(58)
  • 数据库——Redis 没有使用多线程?为什么不使用多线程?

    虽然说 Redis 是单线程模型,但是, 实际上, Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。 不过,Redis 4.0 增加的多线程主要是针对一些大键值对的删除操作的命令,使用这些命令就会使用主处理之外的其他线程来“异步处理”。 大体上来说, Redis 6.0 之前主要还是

    2024年02月11日
    浏览(65)
  • AIGC基础:大型语言模型 (LLM) 为什么使用向量数据库,嵌入(Embeddings)又是什么?

    嵌入: 它是指什么?嵌入是将数据(例如文本、图像或代码)转换为高维向量的数值表示。这些向量捕捉了数据点之间的语义含义和关系。可以将其理解为将复杂数据翻译成 LLM 可以理解的语言。 为什么有用?原始数据之间的相似性反映在高维空间中对应向量之间的距离上。

    2024年02月21日
    浏览(60)
  • 数据库为什么使用B+树而不是B树做索引

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于PHP专栏:MySQL的100个知识点。 🎉欢迎 👍点赞✍评论⭐收

    2024年02月10日
    浏览(48)
  • Facebook 用户量十分庞大,为什么还使用 MySQL 数据库?

    当谈到社交媒体巨头Facebook时,我们立刻想到的是其庞大的用户基础和每日海量的数据流。然而,您可能会惊讶地发现,尽管面对如此巨大的规模,Facebook 仍然选择使用 MySQL 数据库作为其核心的数据存储和管理系统。 为什么Facebook没有选择其他更强大或更高级的数据库系统?

    2024年02月04日
    浏览(50)
  • 为什么 AIGC 和大模型创业者都在安利向量数据库?

    从目前 VC 的投资数据来看,大家对 AI 的关注点主要有三个:一个是基础大模型 LLM,第二个是具体某个场景的应用(包括小模型),第三个就属基础模型与应用层之间的中间层了(开发者工具和数据库等)。 随着开发者疯狂涌入开发各种 AI 应用,中间层已经成为各大 VC 争抢

    2024年02月09日
    浏览(65)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包