- 浏览: 495789 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (502)
- Java (70)
- Linux (10)
- 数据库 (38)
- 网络 (10)
- WEB (13)
- JSP (4)
- 互联网 (71)
- JavaScript (30)
- Spring MVC (19)
- HTML (13)
- CSS (3)
- AngularJS (18)
- Redis (5)
- Bootstrap CSS (1)
- ZooKeeper (4)
- kafka (6)
- 服务器缓存 (4)
- Storm (1)
- MongoDB (9)
- Spring boot (16)
- log4j (2)
- maven (3)
- nginx (5)
- Tomcat (2)
- Eclipse (4)
- Swagger (2)
- Netty (5)
- Dubbo (1)
- Docker (7)
- Hadoop (12)
- OAuth (1)
- webSocket (4)
- 服务器性能 (7)
- Session共享 (1)
- tieye修改 (1)
- 工作 (1)
- 有用的语录 (0)
- https (2)
- common (5)
- 产品开发管理 (1)
- CDN 工作原理 (1)
- APNS、GCM (1)
- 架构图 (3)
- 功能实现分析 (1)
- JMX (1)
- 服务器相关操作命令 (1)
- img02 (0)
- 服务器环境搭建 (9)
- goodMenuBook (1)
- CEInstantPot (0)
- 有用数据 (1)
- 百度地图WEB API (2)
- 正则表达式 (1)
- 样式例子 (2)
- staticRecipePressureCooker.zip (1)
- jCanvas (1)
- 网站攻击方法原理 (1)
- 架构设计 (3)
- 物联网相关 (3)
- 研发管理 (7)
- 技术需求点 (1)
- 计划 (1)
- spring cloud (11)
- 服务器开发的一些实用工具和方法 (1)
- 每天学到的技术点 (4)
- Guava (1)
- ERP 技术注意要点 (2)
- 微信小程序 (1)
- FineRepor (1)
- 收藏夹 (1)
- temp (5)
- 服务架构 (4)
- 任职资格方案 (0)
- osno_test (1)
- jquery相关 (3)
- mybatis (4)
- ueditor (1)
- VueJS (7)
- python (10)
- Spring EL (1)
- shiro (1)
- 前端开发原理与使用 (7)
- YARN (1)
- Spark (1)
- Hbase (2)
- Pig (2)
- 机器学习 (30)
- matplotlib (1)
- OpenCV (17)
- Hystrix (1)
- 公司 (1)
- miniui (4)
- 前端功能实现 (3)
- 前端插件 (1)
- 钉钉开发 (2)
- Jenkins (1)
- elasticSearch使用 (2)
- 技术规范 (4)
- 技术实现原理 (0)
最新评论
原文:http://www.cnblogs.com/Sun_Blue_Sky/articles/2139996.html
数据库的事务隔离级别(TRANSACTION ISOLATION LEVEL)是一个数据库上很基本的一个概念。为什么会有事务隔离级别,SQL Server上实现了哪些事务隔离级别?事务隔离级别的前提是一个多用户、多进程、多线程的并发系统,在这个系统中为了保证数据的一致性和完整性,我们引入了事务隔离级别这个概念,对一个单用户、单线程的应用来说则不存在这个问题。
首先,我们来看一下高并发的系统中会存在哪些问题,为了便于理解我们以张三在招商银行的账号和存款为例。
一、准备工作:
1. 创建一个银行账号Table(只是为了说明问题,不考虑表的设计范式)
CREATE TABLE dbo.BankAccount
(
BankAccountId CHAR(16) NOT NULL, -- 银行账号
UserName NVARCHAR(32) NOT NULL, -- 用户
Balance DECIMAL(19, 2) NOT NULL, -- 余额
LastUpdate SMALLDATETIME NOT NULL
)
GO
2. 准备数据
INSERT INTO dbo.BankAccount
VALUES ('9555500100071120', N'张三', 10000.00, GETDATE()) -- 北京分行账号
INSERT INTO dbo.BankAccount
VALUES ('9555507551227787', N'张三', 20000.00, GETDATE()) -- 深圳分行账号
GO
3. 查看数据
SELECT * FROM dbo.BankAccount
二、应用场景
假设张三在招商银行开设了两个账号,一个是招商银行北京分行,一个是招商银行深圳分行,两个账号的余额分别是10,000和20,000。
1. 张三在网上做了一笔交易,交易额100,买方小王通过银行汇款100到张三的北京分行的账号(见下面左图),柜台操作人员向张三账号存入100(事务一),然后系统些操作日志(假设需要10秒,WAITFOR DELAY '00:00:10')正在此时张三在ATM查了一下账号上余额(事务二),发现已经是10100,于是回去准备发货,但是事务一在写操作日志时超时,这是事务回滚,存款交易被取消,钱退给了小王,这样张三查到的账号余额事实上是事务一还没有提交的数据,导致张三错误的认为已经收到交易款项。
dirtyread1 dirtyread2
一个事务读到另外一个事务还没有提交的数据,我们称之为脏读。(就是数据访问没有互斥)
解决方法:把事务隔离级别调整到READ COMMITTED,即把右上图中的SET TRAN ISOLATION LEVEL READ UNCOMMITTED更改成下图中的SET TRAN ISOLATION LEVEL READ COMMITTED。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果,因为此时事务以已经把自己的更改ROLLBACK了,所以事务二可以返回正确的结果。
2. 张三先后两次查询某一账号的余额,在两次查询期间,小王完成了银行转账,导致两次的查询结果不同。
一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。(数据访问互斥,但对读事件没有互斥,读事务(两次读)还没有完成就让写事务进来了)
解决方法:把事务隔离级别调整到REPEATABLE READ。在下图中使用SET TRAN ISOLATION LEVEL REPEATABLE READ。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
3. 张三妻子先后两次查询张三招商银行所有账号的总余额,而在此期间张三在广州招商银行分行成功开设了一个账号,并存入5000,导致张三妻子两次查询的总余额不同,在此期间张三原有两个账号的余额均未发生改变。
serializable1 serializable2
一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读。(读事务(两次读)还没有完成就让写事务进来了)
解决方法:把事务隔离级别调整到SERIALIZABLE。在下图中使用SET TRAN ISOLATION LEVEL SERIALIZABLE。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
三、总结
事务隔离级别是通过数据库的锁机制来控制的,在不同的应用场景需要应用不同的事务隔离级别,SQL Server默认的事务隔离级别是READ COMMITTED,默认的隔离级别,已经可以满足我们大部分应用的需求。
数据库的事务隔离级别(TRANSACTION ISOLATION LEVEL)是一个数据库上很基本的一个概念。为什么会有事务隔离级别,SQL Server上实现了哪些事务隔离级别?事务隔离级别的前提是一个多用户、多进程、多线程的并发系统,在这个系统中为了保证数据的一致性和完整性,我们引入了事务隔离级别这个概念,对一个单用户、单线程的应用来说则不存在这个问题。
首先,我们来看一下高并发的系统中会存在哪些问题,为了便于理解我们以张三在招商银行的账号和存款为例。
一、准备工作:
1. 创建一个银行账号Table(只是为了说明问题,不考虑表的设计范式)
CREATE TABLE dbo.BankAccount
(
BankAccountId CHAR(16) NOT NULL, -- 银行账号
UserName NVARCHAR(32) NOT NULL, -- 用户
Balance DECIMAL(19, 2) NOT NULL, -- 余额
LastUpdate SMALLDATETIME NOT NULL
)
GO
2. 准备数据
INSERT INTO dbo.BankAccount
VALUES ('9555500100071120', N'张三', 10000.00, GETDATE()) -- 北京分行账号
INSERT INTO dbo.BankAccount
VALUES ('9555507551227787', N'张三', 20000.00, GETDATE()) -- 深圳分行账号
GO
3. 查看数据
SELECT * FROM dbo.BankAccount
二、应用场景
假设张三在招商银行开设了两个账号,一个是招商银行北京分行,一个是招商银行深圳分行,两个账号的余额分别是10,000和20,000。
1. 张三在网上做了一笔交易,交易额100,买方小王通过银行汇款100到张三的北京分行的账号(见下面左图),柜台操作人员向张三账号存入100(事务一),然后系统些操作日志(假设需要10秒,WAITFOR DELAY '00:00:10')正在此时张三在ATM查了一下账号上余额(事务二),发现已经是10100,于是回去准备发货,但是事务一在写操作日志时超时,这是事务回滚,存款交易被取消,钱退给了小王,这样张三查到的账号余额事实上是事务一还没有提交的数据,导致张三错误的认为已经收到交易款项。
dirtyread1 dirtyread2
一个事务读到另外一个事务还没有提交的数据,我们称之为脏读。(就是数据访问没有互斥)
解决方法:把事务隔离级别调整到READ COMMITTED,即把右上图中的SET TRAN ISOLATION LEVEL READ UNCOMMITTED更改成下图中的SET TRAN ISOLATION LEVEL READ COMMITTED。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果,因为此时事务以已经把自己的更改ROLLBACK了,所以事务二可以返回正确的结果。
2. 张三先后两次查询某一账号的余额,在两次查询期间,小王完成了银行转账,导致两次的查询结果不同。
一个事务先后读取同一条记录,但两次读取的数据不同,我们称之为不可重复读。(数据访问互斥,但对读事件没有互斥,读事务(两次读)还没有完成就让写事务进来了)
解决方法:把事务隔离级别调整到REPEATABLE READ。在下图中使用SET TRAN ISOLATION LEVEL REPEATABLE READ。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
3. 张三妻子先后两次查询张三招商银行所有账号的总余额,而在此期间张三在广州招商银行分行成功开设了一个账号,并存入5000,导致张三妻子两次查询的总余额不同,在此期间张三原有两个账号的余额均未发生改变。
serializable1 serializable2
一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读。(读事务(两次读)还没有完成就让写事务进来了)
解决方法:把事务隔离级别调整到SERIALIZABLE。在下图中使用SET TRAN ISOLATION LEVEL SERIALIZABLE。这时我们重复上面的动作会发现事务二会一直等到事务一执行完毕再返回结果。
三、总结
事务隔离级别是通过数据库的锁机制来控制的,在不同的应用场景需要应用不同的事务隔离级别,SQL Server默认的事务隔离级别是READ COMMITTED,默认的隔离级别,已经可以满足我们大部分应用的需求。
发表评论
-
SQL常用语句
2022-07-21 19:09 210delete from cacherefresh where ... -
ES数据同步方案
2022-06-24 10:57 2307//============================= ... -
SQL存储过程例子和有用的SQL
2022-02-19 09:20 198delete from cacherefresh where ... -
SQL优化对比与总结
2021-01-09 14:44 37819000000 b表 SELECT * from b w ... -
执行存储过程测试
2020-12-30 16:47 385--执行存储过程创建 if (exists (select * ... -
mysql提高insert into 插入速度的方法
2018-12-14 17:26 6111mysql提高insert into 插入 ... -
Mysql并发时经典常见的死锁原因及解决方法
2018-12-08 09:30 3063Mysql并发时经典常见的死锁原因及解决方法 MySQL有 ... -
数据库沉余实现方式
2018-12-04 17:30 1021数据库沉余实现方式 canal 原理相对比较简单: (1)c ... -
最终一致性的常用做法
2018-12-01 22:28 641最终一致性的常用做法 ... -
库存扣减和锁
2018-11-29 16:19 2库存扣减和锁 在对数据库的值进行修改时,如果在多线程情况下 ... -
Spring Boot中整合Sharding-JDBC
2018-11-26 18:03 3447Spring Boot中整合Sharding-JDBC ... -
MYSQL 主从、读写分离、分库分表、高可用、数据安全
2018-11-19 18:03 1736MYSQL 主从、读写分离、分库分表、高可用、数据安全 ... -
mybatis-generator 使用
2018-05-19 11:29 562http://www.cnblogs.com/Jason-Xi ... -
eclipse JPA Tools 使用
2018-05-14 17:11 777https://blog.csdn.net/guoxin91/ ... -
mybatis 通用查询实现
2018-03-26 10:04 1425package com.oceano.modity.entit ... -
存储过程 函数
2017-10-27 17:59 475存储过程 函数 存储过 ... -
分页查询例子
2017-10-19 10:22 780分页查询例子 Mybatis分页插件PageHelper的 ... -
数据库同步工具
2017-10-14 14:27 1342数据库同步工具 goden gate Oracle Go ... -
ETL工具
2017-09-01 15:14 761ETL工具 ETL,是英文 Extract-Transfor ... -
PowerDesigner 对比pdm文件内容变化工具
2017-08-06 14:24 704PowerDesigner 对比pdm文件内容变化工具
相关推荐
数据并发的问题 (脏读、不可重复读、幻象读)和数据库锁机制
4. **SERIALIZABLE**:最高隔离级别,防止脏读、不可重复读和幻象读,确保事务间的串行化执行。 【实验步骤】 1. 使用实验一提供的建库脚本和数据插入脚本来创建`Student`数据库。 2. 对每个事务隔离级别,设计...
然而,由于其他事务可能在当前事务的不同阶段提交更改,所以可能出现“不可重复读”,即事务在不同时间读取同一数据时,结果可能不一致。 3. **可重复读(Repeatable Read)**: - 这个级别保证了在一个事务内部,...
- **可串行读(Serializable)**:最高隔离级别,完全避免脏读、不可重复读和幻象读,但可能导致更多的等待和锁冲突。 选择合适的隔离级别需要在数据一致性和系统性能之间找到平衡。 ##### 1.3.2 锁(Lock)机制 ...
它确保在读取数据时,能看到的是一个一致性的视图,即使在高并发环境下,也能够避免脏读、不可重复读和幻象读等现象。这些现象通常是由并发操作未被妥善处理导致的。 #### 事务级别(Transaction Level) 事务级别...
然而,并发执行可能导致脏读、不可重复读和幻读等问题: - 脏读:一个事务读取了另一个未提交事务修改的数据,这在提交读隔离级别下会被阻止。 - 不可重复读:一个事务在不同时间读取同一数据时,由于其他事务的修改...
通过封锁(Locking)等技术,DBMS确保事务在执行时不会看到其他事务未提交的更改,从而避免了诸如丢失更新、脏读、不可重复读和幻读等问题。 4. **持久性**:持久性表示一旦事务提交,其对数据库的更改就会永久保存...
这种隔离级别可以防止脏读,但不能防止不可重复读和幻象读。Oracle 等多数数据库默认都是该级别。 可重复读(Repeated Read)隔离级别可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB 默认级别。在 ...
2. **未确认的相关性(脏读)**:事务读取了另一个事务尚未提交的数据,如果该事务最终回滚,则读取的数据是无效的。 3. **不一致的分析(非重复读)**:同一个事务中多次读取同一行数据,但由于其他事务对该行数据...
- 并发问题:丢失更新、不可重复读、读脏数据、幻象读。 10. **ER图**: - 实体-关系模型,用于描述实体、属性和实体间的关系。 - 局部ER图合并:处理属性冲突、结构冲突和命名冲突。 - E-R图到关系模式的转换...
7. **并发问题**:并发操作可能导致脏读、不可重复读和幻象读等问题。脏读是读取未提交的数据,不可重复读是两次读取同一数据得到不同结果,幻象读则是读取到了其他事务新插入的数据。此外,还有丢失更新问题,分为...
- **不可重复读(Unrepeatable Read)**:事务A在不同时间读取了同一数据的不同版本,因为另一个事务B在这期间修改了数据并提交。 - **幻象读(Phantom Read)**:事务A在两次查询之间,有新的满足查询条件的数据被...
3.4.4 不能装入一个块中的记录 3.4.5 BLOBS 习题 3.5 记录的修改 3.5.1 插入 3.5.2 删除 3.5.3 修改 习题 3.6 小结 3.7 参考文献 第4章 索引结构 4.1 顺序文件上的索引 4.1.1 顺序文件 ...
- **ISOLATION_SERIALIZABLE**:最高隔离级别,完全避免脏读、不可重复读和幻象读,但性能开销较大。 #### 六、示例说明 以示例的形式解释不同隔离级别的差异有助于理解事务隔离级别的实际作用。例如,在`...
`REPEATABLE READ`隔离级别防止了脏读和不可重复读,但在某些情况下仍可能产生幻读。 #### 隔离级别设置 MySQL的默认隔离级别是`REPEATABLE READ`。要查看当前的隔离级别,可以运行`SELECT @@tx_isolation;`。设置...
2.2 DB2 Express-C所不具备的功能...................................................................................23 2.2.1数据库分区......................................................................
Oracle数据库的绑定变量特性是其优化SQL性能的关键技术之一,对于构建高效、可扩展和稳定的数据库系统至关重要。本文将深入探讨绑定变量的原理、优势以及如何在实际应用中使用。 首先,为什么我们要使用绑定变量?...
7. 数据库操作:涉及到数据库连接查询的种类和特点,以及事务相关的知识点,包括事务的定义、实现方式、四大特性(ACID)、隔离级别、脏读、不可重复读和幻象读概念。 8. 菜单模块:在面试中,可能会问及菜单模块的...
2.2 DB2 Express-C所不具备的功能...................................................................................23 2.2.1数据库分区......................................................................