mysql 事务sqlserver_SQLServer数据库:事务与隔离级别实例讲解

本文主要向大家介绍了SQLServer数据库:事务与隔离级别实例讲解,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助。

上班途中,你在一处ATM机前停了下来。正当你在敲入密码的时候,你的一位家人也正在镇上的另一处TAM机上输入密码。你打算从某个还有500元余额的账户上转出400元,而你的家人想从同一账户取走300元。倘若没有隔离级别的存在,麻烦就要来了......

SQL Server 实现了6个隔离级别来防止并发情况下,类似上面例子中企图并发的访问或修改同一数据时问题的发生。本文将带你体验全部6个隔离级别。正如你接下来将看到的,你将理解每个隔离级别所能达成的效果以及何时使用它。

本文假定你对事务和隔离级别的基本概念有所了解。本文所使用的例子基于AdventureWorks数据库而运行。

一、事务简介

SQL Server的6个隔离级别中有5个是用于隔离事务的,它们因而被称作事务隔离级别。另外的一个工作于语句级别。我们先从什么是事务开始吧!

让我们再次回到ATM机的例子。你打算在2个账户间转账。注意,转账至少涉及2个数据更改的操作:一个账户需要减少余额,而另一个账户需要增加余额。好,假定借方账户(debit account)转出资金操作成功了,而贷方账户(credit account)转入资金操作失败了。你不想要这一幕发生,因为那样的话你的钱就没了。你希望两个账户的数据更新作为一个完整的工作单元来处理--要么完全成功,要么完全失败。我们称这样的工作单元为“事务”。事务就是数据库级别的工作单元,包括一个或多个数据更改,必须整体地被视为一个单一的单元,它们要么全都成功,要么什么也不曾发生。

这里再列举几个要求多个数据修改操作必须要么完全成功要么什么也没发生的例子。当数据被合并到数据库时,可能有多个表需要更新。当顾客下订单时,Order表、Invoice Line Item表和Product表的数据可能都需要更新。购买机票也许要求更新Passenger表和Reservations表。无论何时当一个操作要求多个数据更改操作整体地作为单一的单元来处理,这就是需要使用事务的时候。

现在是时候引入2个有用的概念了--提交和回滚。如果事务中所有的数据更改操作都成功了,那么这些数据更改就可以被提交(也就是持久化到数据库)。否则,截止到失败点事务中所发生的所有数据更改必须被回滚(也就是撤销操作,什么也不曾发生)。

现在让我们来看一看使用事务的一些实际命令。在本文的例子中,我们将使用Explicit Transaction Mode。在这种模式下,我们使用BEGIN TRANSACTION 命令开启一个事务,视具体情况,使用COMMIT TRANSACTION 或者 ROLLBACK TRANSACTION 命令终止一个事务。

二、 隔离级别简介

必须小心对待并发情况,因为它们可能引发已知的并发性问题,包括“脏读”、“不可重复读”和“幻像读”,这些问题可能反过来导致数据的不良后果,就像我们在ATM机例子中感受的一样。正如我们已经知道的,为了防止并发性问题,隔离级别用于将事务或语句相互间隔离开来。 下面是SQL Server 2008中定义的隔离级别名称:

A. Transaction Isolation Level

1. READ UNCOMMITTED

2. READ COMMITTED (Default)

3. REPEATABLE READ

4. SERIALIZABLE

5. SNAPSHOT

B. Statement Isolation Level

6. READ COMMITTED SNAPSHOT

正如你在下面的例子中即将看到的,隔离级别越高,提供的保护级别也越高(防止更多的并发性问题)。并且,每个隔离级别包括了前一个级别所提供的保护,因此,每个后续的更高隔离级别以避免更多并发性问题的形式提供了额外的保护。但是,世上没有免费的午餐,隔离级别越高,数据可用性就越低。选择合适的隔离级别是一种在高度安全的并发性和数据的高可用性之间寻求平衡的行为。

让我们来看看具体实例。

三、引入实例

所有例子都运行于AdventureWorks数据库,你可以下载AdventureWorks数据库(AdventureWorks2008_SR4.exe, 包含了除2008R2以外的所有版本AdventureWorks数据库)。

下载本文所有实例的脚本文件

为了创建并发环境,所有例子使用2个SQL Server Session,每个会话运行一个不同的事务,每个事务访问相同的资源。在SQL Server Management Studio中,每个查询窗口代表了一个不同的Session,因此,你可以在SQL Server Management Studio中为不同的事务使用不同的查询窗口。

所有例子包含了真实场景以便你将这一切建立在现实的基础上。

例1. READ UNCOMMITTED 事务隔离级别

READ UNCOMMITTED 事务隔离级别根本就没有提供事务间的隔离,它允许违反并发性原则的最基本形式之一 -- 脏读。当一个事务能够读取另一个事务中已经Update但尚未Commit的数据时,“脏读”就发生了。

READ UNCOMMITTED 事务隔离级别应用于:

· 单用户系统

· 系统中两个事务同时访问同一资源的可能性为零或几乎为零

· 当使用Rowversion数据类型控制并发性时

例2. READ COMMITTED 事务隔离级别

通过仅允许一个事务读取另一个事务中已经提交的数据,READ COMMITTED 事务隔离级别防止了“脏读”问题。这是SQL Server中默认的事务隔离级别。

例3. REPEATABLE READ 事务隔离级别

正如你在前一个事务隔离级别的步骤2所看到的,Session 2中的事务能够修改已经被Session 1中的事务读取的数据。正像真实场景中所描述的,这可能导致“LOST UPDATE”。REPEATABLE READ 事务隔离级别不允许这种情况发生,因为它违背了REPEATABLE READ原则。换句话说,Session 1中的事务读取同一数据可能会产生不同的结果。

例4. SERIALIZABLE 事务隔离级别

为了向你展示SERIALIZABLE 事务隔离级别防止的并发性问题,本例我们从REPEATABLE READ 事务隔离级别开始。

例5. SNAPSHOT事务隔离级别

也许你已经注意到,在上述例1到例4中,防止并发性问题的同时也降低了数据的可访问性。先是不允许Read,然后是不允许Update,不允许Insert。SNAPSHOT事务隔离级别防止了之前那些隔离级别所能防止的许多并发性问题,同时降低了与之相关的成本。它允许更高的数据可用性。

通过在事务开始前在TempDB中使用row versions创建一份数据库的虚拟快照,SNAPSHOT事务隔离级别完成了此壮举。此后它只允许事务访问该数据库虚拟快照。这种方法被称做“基于版本控制的隔离”(versioning-based isolation,背后细节的完整介绍请参考Understanding Row Versioning-Based Isolation Levels。

使用versioning-based isolation,事务仅能看到虚拟快照中的数据。因此,其他事务仍然能够访问同一数据,只要它们不去修改已经被第一个事务修改过的数据就好。如果那样做了(企图修改数据),那么,那些事务将会被回滚并以错误消息终止。

只有当数据库中启用SNAPSHOT事务隔离级别的开关打开后,才能使用它。打开此开关将告知数据库去设置版本化环境。理解这一点很重要,因为,一旦版本化开启,数据库会有维护版本化的开销,无论是否有事务正在使用SNAPSHOT事务隔离级别。

例6. READ COMMITTED SNAPSHOT 隔离级别

到目前为止,所有的隔离级别都是将事务相互间隔离开来。一旦初始事务完成了,对其他事务变得不可用的资源才又变得可用。READ COMMITTED SNAPSHOT 隔离级别在这点上有所不同,它能够读取其已经被他事务提交的数据。

READ COMMITTED SNAPSHOT 隔离级别也是通过数据库开关来打开的。然后,任何使用READ COMMITTED SNAPSHOT 隔离级别的事务将通过版本化起作用。

希望通过以上具体实例,能够帮助你理解如何正确地隔离事务和语句从而防止并发性问题。

四、小结

3a4560a0f5ba9a0fa3a9521fbf4c18b0.png

本文由职坐标整理并发布,希望对同学们学习SQL Server有所帮助,更多内容请关注职坐标数据库SQL Server数据库频道!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/562344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 java springboot+mybatis二手物品网站系统设计和实现

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、Java李杨勇公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 欢迎点赞 👍 收藏 ⭐留言 &#x1f…

AndroidStudio无法新建Java工程解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 以往新建工程都是 New project >> Empty Activity , 有个选择 Java 还是 Kotlin 语言的选项, 之后会默认生成一个 MainActi…

基于java springmvc+mybatis酒水商城管理系统设计和实现

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、【java奥斯卡】公号作者✌ 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 临近学期结束&#xff…

基于java springboot+mybatis爱游旅行平台前台+后台设计实现

我剑最帅 不接受反驳 ​ 项目意义: 改革开放以来, 我国的旅游业发展迅速,但比较而言,我国旅游业发展的广度和深度都远远不能满足经济发展和人民生活水平提高的需要。 随着市场经济的发展和人民收入水平的进一步提高&#xff0c…

《零基础》MySQL 超级入门教程

老规矩 先上镇楼图 MySQL简介 1、什么是数据库 ? 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后&#xff…

bootstarp js设置列隐藏_Bootstrap框架----DataTables列表移动端适配定义隐藏列

我们在上一章节中已经学习了DataTables在BootStrap框架中的使用方式和初始化。Bootstrap框架—-DataTables列表示例最终效果如图:Bootstrap是自动适配移动端的,在手机上查看效果如图:我们发现当数据有很多列时,会存在超出屏幕的可能。这时候表…

《零基础》MySQL 创建数据表(九)

创建MySQL数据表需要以下信息: 表名表字段名定义每个表字段 语法 以下为创建MySQL数据表的SQL通用语法: CREATE TABLE table_name (column_name column_type); 以下例子中我们将在 RUNOOB 数据库中创建数据表runoob_tbl: CREATE TABLE IF…

基于Java jsp+servlet超市订单管理平台设计和实现【建议收藏】

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、Java李杨勇公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 欢迎点赞 👍 收藏 ⭐留言 &#x1f…

《零基础》MySQL 查询数据(十二)

MySQL 数据库使用SQL SELECT语句来查询数据。 你可以通过 mysql> 命令提示窗口中在数据库中查询数据,或者通过PHP脚本来查询数据。 语法 以下为在MySQL数据库中查询数据通用的 SELECT 语法: SELECT column_name,column_name FROM table_name [WHE…

《零基础》MySQL WHERE 子句(十三)

语法 以下是 SQL SELECT 语句使用 WHERE 子句从数据表中读取数据的通用语法: SELECT field1, field2,...fieldN FROM table_name1, table_name2... [WHERE condition1 [AND [OR]] condition2..... 查询语句中你可以使用一个或者多个表,表之间使用逗号…

class h5 点击后样式变化_【php】JQuery怎么实现页面刷新后保留鼠标点击addclass的样式?...

刚开始是这个效果鼠标点击之后变成了这个效果要保证实现 a 标签点击链接一个新的网址同时也要保证效果达到我目前写的网站代码 可以下载http://115.com/file/c2zlhblv看看回答感谢所以回答问题的人。比较好的办法是使用url传参数,然后根据参数判断是否有必要显示cla…

《零基础》MySQL LIKE 子句(十六)

我们知道在 MySQL 中使用 SQL SELECT 命令来读取数据, 同时我们可以在 SELECT 语句中使用 WHERE 子句来获取指定的记录。 WHERE 子句中可以使用等号 来设定获取数据的条件,如 "runoob_author RUNOOB.COM"。 但是有时候我们需要获取 runoob…

《零基础》MySQL UNION 操作符(十七)

描述 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。 语法 MySQL UNION 操作符语法格式: SELECT expression1, expression2, ... expression_n FROM tables [WHERE conditions] UNION [ALL …

《零基础》MySQL 排序(十八)

我们知道从 MySQL 表中使用 SQL SELECT 语句来读取数据。 如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。 语法 以下是 SQL SELECT 语句使用 ORDER BY 子句将查询…

基于java jsp+mybatis+Spring+的SSM二手交易网站设计实现

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、Java李杨勇公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 欢迎点赞 👍 收藏 ⭐留言 &#x1f…

《零基础》MySQL 连接的使用(二十)

在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。 本章节我们将向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询数据。 你可以在 SELECT, UPDATE 和 DELETE…

热榜!基于jsp+mysql的JSP在线水果销售商城系统设计实现【建议收藏】

🍅 作者主页:Java李杨勇 🍅 简介:Java领域优质创作者🏆、Java李杨勇公号作者✌ 简历模板、学习资料、面试题库、技术互助【关注我,都给你】 🍅 文末获取源码联系方式 📝 研究意…

硬核!从0到1学习Spring Cloud微服务章节《建议收藏》

为什么要使用学习springcloud以及他的优势? Spring Cloud 来源于 Spring,质量、稳定性、持续性都可以得到保证。 spirng Cloud 天然支持 Spring Boot,更加便于业务落地。 Spring Cloud 是 Java 领域最适合做微服务的框架。相比于其它框架&…

《springcloud超级入门》Spring Cloud是什么?Spring Cloud版本介绍《二》

Spring cloud是一系列框架的有序集合。它利用 Spring Boot 的开发便利性,巧妙地简化了分布式系统基础设施的开发,如服务注册、服务发现、配置中心、消息总线、负载均衡、断路器、数据监控等,这些都可以用 Spring Boot 的开发风格做到一键启动…

《springcloud超级入门》Spring Cloud和Dubbo的区别及各自的优缺点《三》

了解为什么需要微服务。最初的服务化解决方案是给相同服务提供一个统一的域名,然后服务调用者向这个域发送 HTTP 请求,由 Nginx 负责请求的分发和跳转。 这种架构存在很多问题:Nginx 作为中间层,在配置文件中耦合了服务调用的逻辑…