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 从菜鸟成长为大牛的必经之路

在程序界流行着一种默认的说法叫“黄金5年”,也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向,如何走好这5年,彻底从一个刚入行的菜鸟蜕变成可以以不变应万变的职业大牛&#xf…

java set排序_Java Set排序的方法

Java Set排序的方法Set中TreeSet 本身就是有序的元素,那么下面重点介绍下HashSet的2种排序方法。1. 把HashSet保存在ArrayList里,再用Collections.sort()方法比较private void doSort(){final HashSet va new HashSet();va.add(2007111315);va.add(2007…

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

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

java date 一个月_java中的日期加一个月的计算

Homepage URLhttp://flysky-1.at.vwdhosting.netFTP server name:ftp://flysky-1ftp6.vwdhosting.net Login:flysky-1Password:k%x5WY(0zp? CSDN 论坛 http://www.csdn.net/ 中国最有名的技术论坛,《程序员》杂志就是他们出版的,你可以在上面提出问题&a…

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

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

java多线程中出现的异常分别有哪些_java多线程试题

承Thread类4.线程的高度是指在单个CPU上以某种顺序运行多个线程5.多个线程并发执行时,各个线程中语句的执行顺序是确定的,但是线程之间的相对执行顺序是不确定的6.Java中的对象锁是一种独占的排他锁7.程序中可能出现一种情况:多个纯种互相等待…

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

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

《零基础》MySQL 连接(四)

使用mysql二进制方式连接 实例 以下是从命令行中连接mysql服务器的简单实例: [roothost]# mysql -u root -p Enter password:****** 在登录成功后会出现 mysql> 命令提示窗口,你可以在上面执行任何 SQL 语句。 以上命令执行后,登录成…

java jbutton 禁用_java-禁用后对jButton执行的操作

我有使用Swing的示例代码.package playerlist;import java.awt.FlowLayout;import javax.swing.*;import java.awt.event.*;public class Sample extends JFrame{private JButton button1;private JButton button2;public Sample(){super();setTitle("Sample JFrame"…

《零基础》MySQL 创建数据库(五)

我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 以下命令简单的演示了创建数据库的过程,数据名为 RUNOOB: [roothost]# mysql -u root -p Enter password:****** # 登录后进入终端mysq…

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

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

《零基础》MySQL 删除数据库(六)

使用普通用户登陆 MySQL 服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库,所以我们这边使用 root 用户登录,root 用户拥有最高权限。 在删除数据库过程中,务必要十分谨慎,因为在执行删除命令后,所…

《零基础》MySQL 选择数据库(七)

在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库。 从命令提示窗口中选择MySQL数据库 在 mysql> 提示窗口中可以很简单的选择特定的数据库。你可以使用SQL命令来选择指定的数据库。 实例 以下实例选取了数据…

java biginteger 运算_Java大数字运算之BigInteger 原创

在 Java中,有许多数字处理的类,比如Integer 类。但是Integer 类有一定的局限性,下面我们就来看看比 Integer 类更厉害的一个,BigInteger类。BigInteger类型的数字范围较 Integer 类型的数字范围要大得多。我们都知道 Integer 是 I…

《零基础》MySQL 数据类型(八)

MySQL中定义数据字段的类型对你数据库的优化是非常重要的。 MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。 数值类型 MySQL支持所有标准SQL数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUM…

java线程生命周期_详解java线程的生命周期

详解java线程的生命周期与人有生老病死一样,线程也同样要经历开始(等待)、运行、挂起和停止四种不同的状态。下面百分网小编主要介绍了java 线程的生命周期详解的相关资料,有需要的朋友可以参考!想了解更多相关信息请持续关注我们应届毕业生考试网!一个线…

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

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

java eventbus 原理_EventBus原理解析

前言EventBus的核心思想是观察者模式 (生产/消费者编程模型) 。通过前面的文章我们已经知道,如何使用eventBus了。我们需要先定义一个Observer(前文中的EventListener类),然后将其注册到eventBus里,通过 Subscribe 定义消息回调函数。那我们先…