前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >重学 SQL(七)

重学 SQL(七)

作者头像
1ess
发布2021-10-29 17:59:19
2640
发布2021-10-29 17:59:19
举报
文章被收录于专栏:0x7c00的专栏0x7c00的专栏

重学 SQL(七)

發佈於?2020-08-21

本篇,我们来介绍一下 SQL 中比较重要的知识 —— 事务、事务隔离级别以及不同隔离级别所解决的问题。

事务(Transcation)

事务是指代表单个工作单元的一组 SQL 语句,这些操作要么全做,要么全不做。

ACID 特性

Atomicity

事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。 回滚可以用回滚日志(Undo Log)来实现,回滚日志记录着事务所执行的修改操作,在回滚时反向执行这些修改操作即可。

Consistency

数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对同一个数据的读取结果都是相同的。

Isolation

一个事务所做的修改在最终提交以前,对其它事务是不可见的。

Durability

一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。 系统发生奔溃可以用重做日志(Redo Log)进行恢复,从而实现持久性。与回滚日志记录数据的逻辑修改不同,重做日志记录的是数据页的物理修改。

注意: MySQL 默认采用自动提交模式。也就是说,如果不显式使用 START TRANSACTION 语句来开始一个事务,那么每个查询操作都会被当做一个事务并自动提交。

代码语言:javascript
复制
SHOW VARIABLES LIKE 'autocommit';
-- autocommit ON

创建事务

代码语言:javascript
复制
START TRANSACTION;
...

COMMIT;
-- ROLLBACK;

并发问题

  • Lost Update
  • Dirty Reads
  • Non-Repeating Reads
  • Phantom Reads

标准 SQL 实现了四个事务隔离级别(Isolation Level):

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

隔离级别

脏读

不可重复读

幻读

READ UNCOMMITTED

可能

可能

可能

READ COMMITTED

不可能

可能

可能

REPEATABLE READ

不可能

不可能

可能

SERIALIZABLE

不可能

不可能

不可能

MySQL 中默认的隔离级别是 REPEATABLE READ,它比序列化隔离更快,并且防止了除了幻读之外的大多数并发问题。

修改隔离级别
代码语言:javascript
复制
SHOW VARIABLES LIKE 'transaction_isolation';
-- REPEATABLE-READ

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL SERIALIZABLE;

READ UNCOMMITTED

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT points
FROM customers
WHERE customer_id = 1;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET points = 20
WHERE customer_id = 1;
COMMIT;

当客户端 2 执行 UPDATE 语句之后,COMMIT 之前时,再执行客户端 1 的所有语句,返回结果为 20,产生脏读问题。

READ COMMITTED

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT points
FROM customers
WHERE customer_id = 1;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET points = 20
WHERE customer_id = 1;
COMMIT;

当客户端 2 执行 UPDATE 语句之后,COMMIT 之前时,再执行客户端 1 的所有语句,返回结果为 2273,不会产生脏读问题。

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT points
FROM customers
WHERE customer_id = 1;

SELECT points
FROM customers
WHERE customer_id = 1;
COMMIT;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET points = 20
WHERE customer_id = 1;
COMMIT;

当客户端 1 执行到第一个 SELECT 语句之后,第二个 SELECT 语句之前时,再执行客户端 2 的所有语句,第一个 SELECT 语句返回结果为 2273,第二个 SELECT 语句返回结果为 20,产生不可重复读问题。

REPEATABLE READ

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT points
FROM customers
WHERE customer_id = 1;

SELECT points
FROM customers
WHERE customer_id = 1;
COMMIT;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET points = 20
WHERE customer_id = 1;
COMMIT;

当客户端 1 执行到第一个 SELECT 语句之后,第二个 SELECT 语句之前时,再执行客户端 2 的所有语句,第一个 SELECT 语句返回结果为 2273,第二个 SELECT 语句返回结果为 2273,不会产生不可重复读问题。

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT *
FROM customers
WHERE state = 'VA';
COMMIT;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET state = 'VA'
WHERE customer_id = 1;
COMMIT;

当客户端 1 执行 SELECT 语句之后,COMMIT 之前时,再执行客户端 2 的所有语句,客户端 1 只会查询出 1 条记录,这没问题,因为不会产生脏读和不可重复读问题。但是这时数据库实际有两个 state = ‘VA’ 的记录,但是客户端 1 现在只查询出一条记录,产生幻读问题。

SERIALIZABLE

代码语言:javascript
复制
-- 客户端1
USE sql_store;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT *
FROM customers
WHERE state = 'VA';
COMMIT;

-- 客户端2
USE sql_store;
START TRANSACTION;
UPDATE customers
SET state = 'VA'
WHERE customer_id = 1;
COMMIT;

当客户端 1 执行 SELECT 语句之后,COMMIT 之前时,再执行客户端 2 的所有语句,客户端 1 只会查询出 1 条记录,并且客户端 2 处于阻塞状态。只有当客户端 1 COMMIT/ROLLBACK 之后,客户端 2 才能接触阻塞继续完成事务,所以不会产生幻读问题。

DEADLOCK

数据库死锁问题产生的原因是: 不同事务持有了别的事务需要的锁,两个事务互相等待,从而导致所有事务均无法完成。死锁与隔离级别无关。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 事务(Transcation)
    • ACID 特性
      • Atomicity
      • Consistency
      • Isolation
      • Durability
    • 创建事务
      • 并发问题
        • 修改隔离级别
      • READ UNCOMMITTED
        • READ COMMITTED
          • REPEATABLE READ
            • SERIALIZABLE
              • DEADLOCK
              相关产品与服务
              云数据库 SQL Server
              腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
              http://www.vxiaotou.com