文字直播网站怎么做的,高端装修公司门头设计效果图,应该知道的网站,自己做网站能赚钱前置阅读
快速搭建 Linux 学习平台
一、事务的特性
对于事务#xff0c;我觉得有一句英文描述的非常贴切#xff1a;All or not, now or never. 事务 #xff08;Transaction#xff09;可以说是关系型数据库最重要的特性了。SQL 事务就是一个或者多个 SQL 语句的集合我觉得有一句英文描述的非常贴切All or not, now or never. 事务 Transaction可以说是关系型数据库最重要的特性了。SQL 事务就是一个或者多个 SQL 语句的集合这些 SQL 语句组成了一个单个的逻辑单元所以它只有两种执行结果commit 或者 rollback。学过操作系统的同学都会了解到当程序引入多进程或者多线程时也随之而来的并发问题。同样事务也是为了保证在并发执行的情况下数据的完整性。
事务开启语句是由 begin 或者 start transaction 命令开始的或者把自提交特性关闭set autocommit 0。事务结束语句通常使用 commit 或者 rollback。commit 表示提交事务事务对数据库的修改成为永久性的rollback 表示回滚事务撤销正在进行中的所有未提交的修改。
事务的特性即ACID。 Atomicity 原子性 Consistency 一致性 Isolation 隔离性 Isolation is the database-level property that controls how and when changes are made, and if they become visible to each other, users, and systems. 隔离性是控制修改如何How和 何时When发生以及它们是否对于其它事务、用户和系统是可见的的数据库级别属性。 Durability 持久性
这里只重点介绍 Isolation 隔离性是希望突出重点关于其它三点性质读者可以自行查阅理解。
注acid 在英文有酸性的意思。同样另一个分布式事务它的特性是 base它有碱性的意思。
二、事务的隔离性
MySQL InnoDB 存储引擎实现了 SQL 标准的 4 种隔离级别用来限定事务内外的哪些改变是可见的哪些是不可见的。
MySQL是各个隔离级别分别是 Read Uncommitted 读未提交简称 RU 在一个事务中它可以读取到其他事务还未提交的数据变化这种现象称为脏读。 Read Committed 读已提交简称 RC 在一个事务中可以读取到其他事务已经提交的数据变化这种现象称为不可重复读。 Repeatable Read 可重复读简称 RR 它是 MySQL 默认的事务隔离级别。在一个事务中从它开始直到事务结束都可以反复读取到事务刚开始看到的数据并一直不会发生变化避免了脏读、不可重复读和幻读现象。 Serialization 可串行化 不建议在生产环境使用在某些特殊情况下会使用到。
这四个隔离级别的隔离性是逐渐增大的隔离性越大系统的开销越大。默认的隔离级别是 RR如果实际的应用不需要这个隔离级别可以降低隔离级别这样会提高性能。但是除非你对数据库的隔离级别很了解否则最好只使用默认的隔离级别。
三、隔离性实践
下面会涉及到实际的操作它依赖的环境是前置条件中的那篇快速搭建环境的博客中所搭建的MySQL 8.0。
MySQL 默认的隔离级别是REPEATABLE-READ可重复读简称 RR。
查看默认的隔离级别show variables like %isolation; 或者 select transaction_isolation;修改默认的隔离级别SET transaction_isolation READ-UNCOMMITTED;
注这里要特别注意在命令行中输入不要漏掉了末尾的 ;。 注这里修改的是当前 session 的隔离级别不是全局的隔离级别所以需要在每个终端执行。 创建数据库和测试表
创建并使用数据库CREATE database crazy_dragon;
切换到数据库USE crazy_dragon;
创建测试表
CREATE table t_user_account(id INT NOT NULL AUTO_INCREMENT,name VARCHAR(20) NOT NULL,balance INT NOT NULL,PRIMARY KEY (id)
) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这个表是一个简化的用户账户表idnamebalance。 注意balance 余额。 插入一条测试数据 读未提交 RU
SET transaction_isolation READ-UNCOMMITTED;
在读未提交RU的隔离级别下会出现脏读的现象。这里假设有两个事务简称事务 A 和 事务 B。在事务 A 在执行的过程中它是可以感知到事务 B 的 DML 操作的这样来说其实读未提交就相当于是没有隔离级别了。
事务 A 把 id 1 的用户 tom 的余额更新为 1200接着事务 B 进行查询此时它查出的结果为 1200然后事务 A 回滚。此时数据库中的余额仍为 1000但是事务B读取到了1200这就是脏读。 读已提交 RC
SET transaction_isolation READ-COMMITTED;
在 RC 隔离级别下可以避免脏读。同样事务 A 和事务 B现在的隔离级别是读已提交。所以只有已经提交的数据才可以被另一个事务感知到这样就不会发生脏读了。 读已提交避免了脏读现象但是还有不可重复读和幻读问题。不可重复读指的是在一个事务范围内多次查询结果字段值不同。幻读值的是在一个事务范围内多次查询结果行数不同。所以这里要注意区分这两个的区别不可重复读强调是是字段值幻读强调的是数据结果的行数。
下面来分别演示不可重复读和幻读的情况。 第二个事务前后两次查询的的 balance 字段结果不同这就是不可重复读update。多次读取的结果无法确定无法确定另一个事务的改动。 第二个事务两次查询的结果行数不一致这就是幻读insert。
幻读和不可重复读很相似但是幻读强调的是查询结果集合的增减而不是单条数据的更新。
可重复读 RR
默认的隔离级别Repeatable Read简称 RR。可以解决不可重复读和幻读。
set transaction_isolation REPEATABLE-READ
下面分别演示了在 RR 隔离级别下不可重复读和幻读问题被解决。 参考博客
Understanding the Isolation Property in a Database (lifewire.com)
MySQL :: MySQL 8.0 Reference Manual :: 15.7.2.1 Transaction Isolation Levels
A primer on sql transactions