Mariadb之事务隔离级别 – Linux「终于解决」

Mariadb之事务隔离级别 – Linux「终于解决」上一篇我们聊到了mariadb的锁,以及怎么手动加锁和解锁等等,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13196905.html;今天我们来聊一聊mar

Mariadb之事务隔离级别 - Linux

  上一篇我们聊到了mariadb的锁,以及怎么手动加锁和解锁等等,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13196905.html;今天我们来聊一聊mariadb的事务隔离级别;在前边的随笔中,我们提到到了mysql的存储引擎,常用的有MyISAM和innodb,其中myisam不支持事务,innodb支持事务;所以我们常说的事务是针对innodb存储引擎来说的;所谓事务就是在我们在执行大批量语句时,为了保证数据库的完整性,要么语句全部执行,要么语句全部不执行;所以事务必须满足ACID这是个条件;A表示Atomicity,原子性,也是不可分性;C表示Consistency,一致性;I表示Isolation,隔离性,又称独立性;D表示Durability,持久性;所谓原子性,就是事务中执行的语句要么全部执行,要么全部不执行,如果事务在中途发生错误,那么前面执行过的语句将会回滚到事务前;一致性指的是在执行事务之前和事务执行完成后的数据库状态是完整的;也就是说我们执行的语句都按照我们预想的结果执行了;隔离性指数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。持久性指的是,事务执行完成后,对数据的修改是永久的;

  接下来我们来说说怎么在mariadb中开启事务吧

  用户手动开启事务用start transaction 或者使用begin语句开启事务;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:以上红框中的语句就表示手动开启一个事务;这里需要注意一点,对于mysql来讲,默认在命令行执行的语句都是自动提交事务的;也就是说默认情况下我们在mysql shell中执行的语句它默认也会开启一个事务,但我们语句执行完成后,它会自动把该事务提交;所以我们手动开启一个事务可以使用start transaction 语句 或者begin 或者执行set autocommit=0来关闭自动提交事务;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:提交事务用commit 语句,表示结束当前事务;当然结束当前事务也可以用rollback语句,表示回滚到事务之前的状态;回滚以后事务也就结束了;

  SAVEPOINT identifier:创建一个保存点,一个事务中可以存在多个保存点,回滚时我们可以指定回滚到某个点上;

MariaDB [first_db]> begin;
Query OK, 0 rows affected (0.000 sec)

MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
+------+----------+------+
2 rows in set (0.001 sec)

MariaDB [first_db]> insert into test_tb values (3,"lisi",23);
Query OK, 1 row affected (0.002 sec)

MariaDB [first_db]> savepoint one;
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> insert into test_tb values (4,"wangwu",25);
Query OK, 1 row affected (0.001 sec)

MariaDB [first_db]> savepoint two;
Query OK, 0 rows affected (0.000 sec)

MariaDB [first_db]> select * from test_tb;                   
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
|    3 | lisi     |   23 |
|    4 | wangwu   |   25 |
+------+----------+------+
4 rows in set (0.001 sec)

MariaDB [first_db]> rollback to one;
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
|    3 | lisi     |   23 |
+------+----------+------+
3 rows in set (0.001 sec)

MariaDB [first_db]>

代码100分

  提示:存在多个保存点,如果回滚到前边的点以后,后面的保存点就没有了;

  接下来看看事务的隔离级别

  对于mysql数据库 innodb存储引擎支持的事务隔离级别有4中,READ-UNCOMMITED:读未提交;这表示事务还没有结束,其他用户或进程是可以实时的读到事务中对数据的改变,因为事务还没提交,所以我们认为其他用户或进程读到的数据就是一个不准确的数据,通常我们把这种叫脏读;READ-COMMITTED:读提交;这表示只有事务提交后,其他用户或进程才可以读到事务修改后的数据;这种事务隔离级别就要比前面的隔离级别要高一点,读到的数据也要精准一点;这种隔离级别就是只要事务A提交了,在其他事务里就可以读取到事务A修改后的数据;通常这种我们叫不可重复读,不可重复读表示在其他事务中,读到的数据是根据事务A是否提交有关系;REPEATABLE-READ:可重复读,这表示在A事务中修改后的数据,在B中事务上不可见的,即便A中事务已经提交,B中事务没有提交,那么在B中的事务中读到的还是A事务修改前的数据;只有当事务B结束后才能读到A事务修改后的数据;所以通常我们把这种方式也叫幻读,给人一种幻觉的感觉;SERIALIZABLE:串行化;这种隔离级别是最高的,但同时并发访问也是最差的,它表示事务A和事务B是顺序执行的,什么意思呢,就是说事务B必须要等到事务A完成后才可以执行;

  关闭自动提交功能

代码100分MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> set @@session.autocommit=0;
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> 

  提示:以上语句表示设定当前会话关闭自动提交功能,关闭此会话它将恢复原有设定;

  设置事务A的隔离级别为read-uncommitted

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:事务隔离级别字串要加引号,否则会提示语法错误

  设置会话B的隔离级别为read-uncommitted

Mariadb之事务隔离级别 - Linux「终于解决」

  在事务A中修改表中数据,在会话B中查看表中数据,看看是否在会话B中看到修改后的数据?

MariaDB [first_db]> BEGIN;
Query OK, 0 rows affected (0.000 sec)

MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ        |
+------------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> set @@session.tx_isolation="read-uncommitted";
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> select @@session.tx_isolation;                
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
+------+----------+------+
2 rows in set (0.001 sec)

MariaDB [first_db]> insert into test_tb values(2,"xiaohong",33);
Query OK, 1 row affected (0.001 sec)

MariaDB [first_db]> select * from test_tb;                      
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
|    2 | xiaohong |   33 |
+------+----------+------+
3 rows in set (0.001 sec)

MariaDB [first_db]> 

  提示:在事务A中插入数据在当前事务中是可以正常看到数据的变化;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:可以看到在会话B上是可以正常看到事务A中数据的修改;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:从上面的信息可以看到,当事务A中的修改操作回滚时,在会话B中是可以查看到回滚后的数据;这也意味这在会话B中读到的数据不是很准确;

  设置事务A的事务隔离级别为read-committed
Mariadb之事务隔离级别 - Linux「终于解决」

  设置会话B的事务隔离级别为read-committed,然后在事务A上修改数据,不提交,看看会话B上是否可以看到?

代码100分MariaDB [first_db]> start transaction;
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> set @@session.tx_isolation="read-committed";
Query OK, 0 rows affected (0.001 sec)

MariaDB [first_db]> select @@session.tx_isolation;              
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-COMMITTED         |
+------------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
|                    0 |
+----------------------+
1 row in set (0.001 sec)

MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
+------+----------+------+
2 rows in set (0.001 sec)

MariaDB [first_db]> insert into test_tb values(3,"wangwu",43);  
Query OK, 1 row affected (0.001 sec)

MariaDB [first_db]> select * from test_tb;                    
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | xiaoming |   44 |
|    2 | zhangsan |   16 |
|    3 | wangwu   |   43 |
+------+----------+------+
3 rows in set (0.001 sec)

MariaDB [first_db]> 

  在会话B中查看test_tb表,看看是否有能看到修改后的数据?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:在会话B中可以看到的test_tb表中的数据还是事务A开始前的数据;

  提交事务A,看看会话B是否能够看到修改后的数据呢?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:可以看到当事务A提交以后,在会话B中就可以看到事务A中修改后的数据;

  设置事务A的事务隔离级别为repeatable-read

MariaDB [first_db]> begin;
Query OK, 0 rows affected (0.000 sec)

MariaDB [first_db]> set @@session.tx_isolation="repeatable-read";
Query OK, 0 rows affected (0.000 sec)

MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ        |
+------------------------+
1 row in set (0.000 sec)

MariaDB [first_db]> 

  关闭事务B的自动提交功能并设置事务B的隔离级别为repeatable-read 

Mariadb之事务隔离级别 - Linux「终于解决」

  在事务A中修改数据,并提交,看看在事务B中是否能看到修改后的数据?

Mariadb之事务隔离级别 - Linux「终于解决」

  在事务B中查看test_tb表中的数据,看看是否有变化呢?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:可以看到在事务B中无论怎么查看数据都是没有发生变化;

  提交事务B在查看数据看看是否有变化?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:可以看到当事务B提交以后,再次查看表中数据,就可以看到事务A更改以后的表数据了;

  设置会话A的事务隔离级别为serializable

Mariadb之事务隔离级别 - Linux「终于解决」

  设置会话B的事务隔离级别为serializable

Mariadb之事务隔离级别 - Linux「终于解决」

  在事务A,事务B中更新表中同一条数据,看看会发生什么?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:在事务B中成功修改了第一条数据;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:在事务A上就不能修改第一条数据了,那我们在事务A上是否可修改第二条数据呢?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:可以看到第二条数据是能够修改的;

  提交事务B,看看A事务上是否可以修改第一条数据呢?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:提交了事务B以后,在会话B上再次查看test_tb表中的数据,发现执行不了,原因是事务A修改了第二条数据,还未完成事务,所以一直阻塞;

  在事务A上修改第一条数据,看看是否可修改?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:提交了事务B以后,在事务A上还是不能够修改第一条数据;原因是事务A修改了第二条数据,事务还没有结束,所以第三个事务就无法执行,所以我们在会话B上是不能够查看数据,因为默认情况查看数据也会启动一个事务;

  结束事务A,在会话B上看看是否可查询?

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:回滚了事务A,事务A也就结束了;在事务B中修改的数据,在事务A上做回滚,是回滚不回去的;这说明回滚操作只针对当前事务;

Mariadb之事务隔离级别 - Linux「终于解决」

  提示:结束了事务A以后,在会话B上就可以正常查看test_tb上的数据了;

  以上就是在mariadb数据库上的事务的四种隔离级别的区别;从上面的演示可以看到,串行化的隔离级别最高,但是并发连接也是最差的,因为它必须要等到前一个事务结束后才可以执行后面的事务;其次就是可重读,可重读必须是两个事务都结束以后才可以看到真实修改后的数据;再其次就是不可重读,读提交,这种隔离级别必须是一方事务提交以后其他事务才可以读到真实修改数据;而隔离级别最低就是对未提交,这种隔离级别只要是事务中修改了,其他事务上就能够读到相应的数据;当然这种读到的数据也是最不靠谱的;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7682.html

(0)
上一篇 2023-03-16
下一篇 2023-03-16

相关推荐

  • .NET 链接数据库:证书链是由不受信任的颁发机构颁发的[通俗易懂]

    .NET 链接数据库:证书链是由不受信任的颁发机构颁发的[通俗易懂]错误信息 证书链是由不受信任的颁发机构颁发的 错误环境 .NET web.config链接数据库(发布到服务)时报错 解决方法 下面配置标红部分在你的代码配置中增加或者修改 <add name=

    2023-03-06
    147
  • mysql的知识点_必修一地理知识点总结

    mysql的知识点_必修一地理知识点总结MySQL学习笔记 登录和退出MySQL服务器 # 登录MySQL $ mysql -u root -p12345612 # 退出MySQL数据库服务器 exit; 基本语法 — 显示所有数据库 s

    2023-05-09
    149
  • Python字符串转Byte

    Python字符串转Byte在Python中,字符串和Byte是不同的数据类型。字符串是一组字符序列,而Byte是一组二进制数据。Python中的字符串不支持直接转换为Byte,因此我们需要使用一些方法来完成这个操作。

    2024-07-17
    43
  • 对数据表中某2列的值对调

    对数据表中某2列的值对调如标题所言,需要把2列的数据进行对调,列1的值存入列2,把列2的值存储列1中去。 如何实现,2种方法: 第1种,对列名进行修改,把name1改为name2,把name2改为name1即可: sp_re

    2022-12-29
    155
  • 用Python构建强大的对象导向程序

    用Python构建强大的对象导向程序Python是一种动态、解释性、高级编程语言,被广泛用于数据科学、机器学习、Web应用开发等领域。Python的强大之处在于它提供了多种编程风格,其中面向对象编程(Object Oriented Programming,简称OOP)是最为流行且有效的方式之一。本文旨在探讨如何用Python构建强大的对象导向程序,分别从以下几个方面展开。

    2024-02-12
    87
  • rocksdb使用_flink写入kafka

    rocksdb使用_flink写入kafkaRocksDB介绍RocksDB简介RocksDB是基于C++语言编写的嵌入式KV存储引擎,它不是一个分布式的DB,而是一个高效、高性能、单点的数据库引擎。它是由Facebook基于Google开源的

    2023-01-26
    166
  • 电脑换硬盘要重装系统吗[亲测有效]

    电脑换硬盘要重装系统吗[亲测有效]不少用户想知道电脑换硬盘了,还要重装系统吗? 一、如果这个硬盘是全新的,换到另一台主机上,这时是需要重装系统的,可以使用U盘来安装系统。 二、如果硬盘里已有系统,而且系统能够正常使用,换到另一台主机…

    2023-04-10
    161
  • mysql基本数据类型_以下哪些是mysql数据类型

    mysql基本数据类型_以下哪些是mysql数据类型2020年4月27日 8:22 1、整型 类型: 字节大小 数值范围 Tinyint 1 有符号:-128~127 无符号: 0~255 smallint 2 有符号:-32768~32767 无符号

    2023-02-24
    133

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注