谈谈数据库的ACID

article/2025/9/29 20:48:25

谈谈数据库的ACID

                                                                                                                                                                  帅宏军

一.事务

       定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

       准备工作:为了说明事务的ACID原理,我们使用银行账户及资金管理的案例进行分析。

 

       

       // 创建数据库create table account(idint primary key not null,namevarchar(40),moneydouble);// 有两个人开户并存钱insert into account values(1,'A',1000);insert into account values(2,'B',1000);


二.ACID

       ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability.这是可靠数据库所应具备的几个特性.下面针对这几个特性进行逐个讲解.


三.原子性

       原子性是指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。

       1.案例

              AB转帐100元钱

 

       

       begin transactionupdate account set money= money - 100where name='A';update account set money= money +100where name='B';if Error thenrollbackelsecommit

 

       2.分析 

       在事务中的扣款和加款两条语句,要么都执行,要么就都不执行。否则如果只执行了扣款语句,就提交了,此时如果突然断电,A账号已经发生了扣款,B账号却没收到加款,在生活中就会引起纠纷。

 

       3.解决方法

       在数据库管理系统(DBMS)中,默认情况下一条SQL就是一个单独事务,事务是自动提交的。只有显式的使用start transaction开启一个事务,才能将一个代码块放在事务中执行。保障事务的原子性是数据库管理系统的责任,为此许多数据源采用日志机制。例如,SQL Server使用一个预写事务日志,在将数据提交到实际数据页面前,先写在事务日志上。


四.一致性

       一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。

       1.案例

       对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNT表中aaabbb的存款总额为2000元。

 

       2.解决方法

保障事务的一致性,可以从以下两个层面入手

       2.1数据库机制层面

       数据库层面的一致性是,在一个事务执行之前和之后,数据会符合你设置的约束(唯一约束,外键约束,Check约束等)和触发器设置。这一点是由SQL SERVER进行保证的。比如转账,则可以使用CHECK约束两个账户之和等于2000来达到一致性目的

       2.2业务层面

   对于业务层面来说,一致性是保持业务的一致性。这个业务一致性需要由开发人员进行保证。当然,很多业务方面的一致性,也可以通过转移到数据库机制层面进行保证。


五.隔离性

       多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。

       这指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

       Windows中,如果多个进程对同一个文件进行修改是不允许的,Windows通过这种方式来保证不同进程的隔离性:

   

       企业开发中,事务最复杂问题都是由事务隔离性引起的。当多个事务并发时,SQL Server利用加锁和阻塞来保证事务之间不同等级的隔离性。一般情况下,完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样会严重影响性能。想要理解SQL Server中对于隔离性的保障,首先要了解并发事务之间是如何干扰的.

       1.事务之间的相互影响

       事务之间的相互影响分为几种,分别为:脏读,不可重复读,幻读,丢失更新

 

       1.1脏读

       脏读意味着一个事务读取了另一个事务未提交的数据,而这个数据是有可能回滚的;如下案例,此时如果事务1回滚,则B账户必将有损失。

     

 

       1.2不可重复读

    不可重复读意味着,在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。如下案例,事务1必然会变得糊涂,不知道发生了什么。

 

       1.3幻读(虚读)

    幻读,是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.

  

 

       1.4丢失更新

       两个事务同时读取同一条记录,A先修改记录,B也修改记录(B是不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。

 

       2.理解SQL SERVER中的隔离级别

       数据库的事务隔离级别(TRANSACTION ISOLATION LEVEL)是一个数据库上很基本的一个概念。为什么会有事务隔离级别,SQL Server上实现了哪些事务隔离级别?事务隔离级别的前提是一个多用户、多进程、多线程的并发系统,在这个系统中为了保证数据的一致性和完整性,我们引入了事务隔离级别这个概念,对一个单用户、单线程的应用来说则不存在这个问题。

    为了避免上述几种事务之间的影响,SQL Server通过设置不同的隔离级别来进行不同程度的避免。因为高的隔离等级意味着更多的锁,从而牺牲性能。所以这个选项开放给了用户根据具体的需求进行设置。不过默认的隔离级别Read Commited符合了多数的实际需求.

 

隔离级别

脏读

丢失更新

不可重复读

幻读

并发模型

更新冲突检测

未提交读:Read Uncommited

悲观

已提交读:Read commited

悲观

可重复读:Repeatable Read

悲观

可串行读:Serializable

悲观

    

       SQL Server隔离事务之间的影响是通过锁来实现的,通过阻塞来阻止上述影响。不同的隔离级别是通过加不同的锁,造成阻塞来实现的,所以会以付出性能作为代价;安全级别越高,处理效率越低;安全级别越低,效率高。

 

       使用方法:SET TRANSACTIONISOLATION LEVEL REPEATABLE READ

 

       未提交读: 在读数据时不会检查或使用任何锁。因此,在这种隔离级别中可能读取到没有提交的数据。  

       已提交读:只读取提交的数据并等待其他事务释放排他锁。读数据的共享锁在读操作完成后立即释放。已提交读是SQL Server的默认隔离级别。 

       可重复读: 像已提交读级别那样读数据,但会保持共享锁直到事务结束。  

       可串行读:工作方式类似于可重复读。但它不仅会锁定受影响的数据,还会锁定这个范围。这就阻止了新数据插入查询所涉及的范围。


六.持久性

       持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

       即使出现了任何事故比如断电等,事务一旦提交,则持久化保存在数据库中。

       SQL SERVER通过write-ahead transaction log来保证持久性。write-ahead transaction log的意思是,事务中对数据库的改变在写入到数据库之前,首先写入到事务日志中。而事务日志是按照顺序排号的(LSN)。当数据库崩溃或者服务器断点时,重启动SQL SERVERSQLSERVER首先会检查日志顺序号,将本应对数据库做更改而未做的部分持久化到数据库,从而保证了持久性。


七.总结

       事务的(ACID)特性是由关系数据库管理系统(RDBMS,数据库系统)来实现的。数据库管理系统采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所做的更新,如果某个事务在执行过程中发生错误,就可以根据日志,撤销事务对数据库已做的更新,使数据库退回到执行事务前的初始状态。

  数据库管理系统采用锁机制来实现事务的隔离性。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。


转载请注明出处:http://blog.csdn.net/shuaihj/article/details/14163713



http://chatgpt.dhexx.cn/article/BL265vE3.shtml

相关文章

数据库中的 ACID 属性

💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 大多数使用数据库的程…

什么是ACID?它的特性是什么?

https://baijiahao.baidu.com/s?id1743501877867119042&wfrspider&forpc ACID是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性&…

事务ACID理解

事务管理(ACID) 谈到事务一般都是以下四点 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 一致性(Consistency) 事务前后数据…

vue页面刷新 reload()

首先在vue里配置 在所想添加reload的vue里直接如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190610082256841.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTAxMTkxMA…

重识Nginx - 16 Nginx reload流程浅析

文章目录 图解reload流程1.向master程发送HUP号( reload命令)2.master进程校验配置语法是否正确3.master进程打开新的监听端口4.master进程用新配置启动新的worker 进程5.master进程向老worker 进程发送QUIT号6.老worker进程关闭监听句柄,处理完当前连接后结束进程 图解reload流…

vue this.reload 方法 配置, 优于window.reload()的页面刷新

相关网址: https://www.cnblogs.com/yinn/p/9056731.html 1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求。 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.re…

Nginx reload

解释 /usr/local/nginx/sbin/nginx -s reload 用过多次这条命令,一直以为是重启Nginx,今天有幸看了下Nginx官方文档介绍这条命令 Nginx服务不会终止,主进程检查配置,应用配置的过程。主进程会启动一个新的工作进程处理新来的请求…

layui table.reload()

使用table.reload()重载去搜索特定列 html <div class"searchTable" id"searchTable"><div class"layui-inline"><input class"layui-input layui-inline" id"badge" placeholder"badge" autoc…

为什么 NGINX 的 reload 命令不是热加载?

这段时间在 Reddit 看到一个讨论&#xff0c;为什么 NGINX 不支持热加载&#xff1f;乍看之下很反常识&#xff0c;作为世界第一大 Web 服务器&#xff0c;不支持热加载&#xff1f;难道大家都在使用的 nginx -s reload 命令都用错了&#xff1f;带着这个疑问&#xff0c;让我们…

Unity 手动编译 Reload脚本 减少等待时间

Unity 手动编译 Reload 脚本 这是个自定义reload domain工具,加快工作流,减少等待.测试版本是Unity2021,理论上来说2020以上都可. 脚本地址:UnityManualReload (github.com) 在Unity中遇到的问题 在unity工作流中,修改脚本->编译脚本->reload domain(重载域)-> 进…

layui table reload 重载

在所有记录中通过姓名搜索需要的数据&#xff0c; 搜索记录为空时返回所有记录 HTML&#xff1a; 方法渲染table&#xff1a; 表格重载&#xff1a; reload将再次访问servlet 第一次访问&#xff1a; reload访问&#xff1a; ennn&#xff0c;然后就是后台操作了&#xff0c;我…

搬运 auto_reload preload

原文&#xff1a; STM32CubeMX配置时钟中的auto-reload precload_飞由于度的博客-CSDN博客 STM32的定时器开发基础的时候&#xff0c;产生了一个疑问&#xff0c;这里不需要使能自动重装载吗&#xff1f; 带着这个疑问我去查了一下《STM32 HAL 库开发实战指南》&#xff0c;在…

4、Nginx命令(reload很重要)

Nginx命令&#xff08;reload很重要&#xff09; ./nginx -s reload &#xff1a;当我们更改了配置文件&#xff0c;我们都要重新加载我们的配置文件也就是reload例如我们的更改端口号变80位8080 连接不上的操作

js 刷新当前页面的方法 reload() , replace()的简单使用

本文为大家介绍三种 js 刷新当前页面的方法&#xff0c;我是在vue实例下写的&#xff1a; 添加定时器是为了直观看到刷新效果&#xff08;每次刷新都会重置为0&#xff09;&#xff1b; reload() 方法; replace() 方法; 页面自动刷新; reload() 方法 reload()方法用于刷新当…

SVN 服务器的搭建

当做大的项目是&#xff0c;svn是代码管理的好工具&#xff0c;如果是用自己的服务器&#xff0c;那么需要搭建SVN服务器。 Subversion是一款非常优秀的svn服务器工具&#xff0c;笔者采用VisualSVN server &#xff0c;因为它集成了apache,不用再进行过多的配置。 首先下载安…

SVN服务器搭建与使用

TortoiseSVN&#xff08;1.9.5&#xff09;与VisualSVN Server搭建SVN版本控制系统&#xff08;中文版&#xff09; 参考文献&#xff1a;http://www.cnblogs.com/xing901022/p/4399382.html 本片主要介绍如何搭建SVN版本控制系统&#xff0c;主要使用工具&#xff1a; 1. 服…

svn的搭建和使用

一&#xff1a;SVN服务器搭建和使用。 1. 首先来下载和搭建SVN服务器,下载地址如下: http://subversion.apache.org/packages.html&#xff0c;进入网址后&#xff0c;滚动到浏览器最底部看到如下截图&#xff1a; 个人认为最好用VisualSVN server 服务端和 TortoiseSVN客户…

Windows-Linux下的SVN服务器搭建及SVN操作

一、Windows下的SVN服务器搭建 首先准备一下三个软件&#xff1a; 1. VisualSVN-Server-3.8.0-x64.msi&#xff08;svn服务端&#xff09; 2. TortoiseSVN-1.9.6.27867-x64-svn-1.9.6.msi&#xff08;svn客户端&#xff09; 3. TortoiseSVN中文语言包_1.9.6.27867-x64-zh_…

SVN服务器搭建、客户端安装超详细图解教程

目录 一、安装包下载 1.下载 TortoiseSVN 服务器安装包 2.下载 TortoiseSVN 客户端安装包 二、详细安装过程图解 1.TortoiseSVN 服务器安装 2.TortoiseSVN 客户端安装 一、安装包下载 1.下载 TortoiseSVN 服务器安装包 >> 官网下载 Windows 平台安装包在网页最底…

linux下svn服务器搭建及使用(包含图解)

今天自己动手在linux搭建了svn服务器&#xff0c;把具体过程和一些自己的见解分享给大家&#xff0c;希望对大家有所帮助。   客户端svn&#xff08;大家见到的小乌龟&#xff09;下载地址为&#xff1a;http://tortoisesvn.net/downloads.html。这里客户端的安装就不作详解…