数据库事务的四大特性以及事务的隔离级别

本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别。

  如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:

⑴ 原子性(Atomicity)

  原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

⑵ 一致性(Consistency)

  一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。

  拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

⑶ 隔离性(Isolation)

  隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。

  即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

  关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。

⑷ 持久性(Durability)

  持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

  例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

  

  以上介绍完事务的四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:

1,脏读

  脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

  当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

    update account set money=money+100 where name=’B’;  (此时A通知B)update account set money=money - 100 where name=’A’;

  当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

2,不可重复读

  不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

  例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

  不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

  在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

3,虚读(幻读)

  幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

  幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

 

  现在来看看MySQL数据库为我们提供的四种隔离级别:

  ① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

  ② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

  ③ Read committed (读已提交):可避免脏读的发生。

  ④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

 

  以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

  在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别

  在MySQL数据库中查看当前事务的隔离级别:

    select @@tx_isolation;

  在MySQL数据库中设置事务的隔离 级别:

    set  [glogal | session]  transaction isolation level 隔离级别名称;set tx_isolation=’隔离级别名称;’

例1:查看当前事务的隔离级别:

  

例2:将事务的隔离级别设置为Read uncommitted级别:

  

或:

  

记住:设置数据库的隔离级别一定要是在开启事务之前!

  如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connection对象的setAutoCommit(false)方法之前。调用Connection对象的setTransactionIsolation(level)即可设置当前链接的隔离级别,至于参数level,可以使用Connection对象的字段:

  

在JDBC中设置隔离级别的部分代码:

  

  后记:隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

 

参考博客:

http://www.zhihu.com/question/23989904

http://dev.mysql.com/doc/refman/5.6/en/set-transaction.html

http://www.cnblogs.com/xdp-gacl/p/3984001.html

转载于:https://www.cnblogs.com/chenjunsheng/p/10448254.html

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

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

相关文章

程序员面试的一些注意点

一、前言 自己即将踏上求职的征程,所以整理一篇有关于程序员面试的小窍门,帮助自己和正在求职、即将求职的一些小伙伴跳过一些坑。 二、简历制作1. 不要放头像普通人大概率都不是帅哥美女,所以不想让外观成为评判标准的就不要放照片上去了。2…

如何解决数据倾斜问题?

转载:https://blog.csdn.net/Mr_HHH/article/details/89399518 今天在工作中遇到了数据倾斜的问题,一条SQL执行了8小时才执行完,看计划是先join再做distinct,卡在了join上,数据量比较大,并且重复数据比较多…

白盒测试不是测试,更不高级

测试不仅仅是软件概念,但白盒测试仅仅是软件概念。 上面这句话足以说明白盒测试不是测试,至少不等同于测试。 认为白盒测试更牛逼的一个常用论据是白盒测试需要对代码本身更高的熟悉程度,但说这样的话的人往往没有搞清楚测试究竟需要什么样的…

剑指Offer题解(Python版)

https://blog.csdn.net/tinkle181129/article/details/79326023# 二叉树的镜像 链表中环的入口结点 删除链表中重复的结点 从尾到头打印链表 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 把字符串转换成整数 平衡二叉树 和为S的连续正数序列 左…

Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]

今天看看Paypal支付流程和简单的认证原理,我画了一张图.应该能表达这两点意思了我们的站点名字,为了好理解,暂且就定为西狐的网站吧.点此查看清晰原图恩,理论知识很重要哈,先把这图理解了,下一步我们编程使用沙盒测试就很简单了.如果想更多研究一下还可直接查看Paypal官方提供的…

C语言指针深度理解

指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; 能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。指针极大…

PLSQL DEVELOPER 使用技巧

为什么80%的码农都做不了架构师?>>> 1、右键菜单 在PL/SQL Developer(下面简称PLD)中的每一个文本编辑窗口,如SQL Window,Command Window和Porgram Window,右键点击某个对象名称,会…

为什么不能同时用const和static修饰成员函数?

const修饰的函数: 表示在该函数体内不能修改成员的值,会在函数中添加一个隐式的参数const this*. static修饰的函数没有this指针,与const的用法冲突。 但可以使用static和const修饰成员。 例子如下: class Singleton { public: stati…

对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。

typedef struct TNode { int data; TNode* left; TNode* right; TNode* next; }; //时间复杂度为O(n)&#xff0c;空间复杂度为O(n) void addNext(TNode* root) { if (!root) { return; } queue<TNode*> q; q.push(root); while (!q.empty()) { int levelL…

T-SQL DML学习笔记

1. select 语句的基本结构是 select -->From-->where group By Having Order By 2. Exists 条件 Exists 后面括号内的条件语句如果为真的话 这此次查询继续 &#xff0c;如Exists跟的条件语句没有查询到数据则前面语句块的查询不再执行下去 select province…

反射--Class获得

/* Java提供3种方式获得Class对象 * * 不同应用场景&#xff0c;需要不同的方式获得Class对象 * * 方式&#xff1a; * 1.通过字符串&#xff08;全限定类名&#xff09;获得 * 格式&#xff1a;Class clazz Class.forName("字符串"); * 全限定类名&#xff1a;包名…

Android Drawable绘图学习笔记

如何获取 res 中的资源 数据包package&#xff1a;android.content.res 主要类&#xff1a;ResourcesAndroid SDK中的简介&#xff1a;Class for accessing an application’s resources.Class for accessing an application’s resources. This sits on top of the asset mana…

在类中调用delete this问题

转载&#xff1a;https://blog.csdn.net/kuimzzs/article/details/81517451 很多时候&#xff0c;一些定义在类内的变量的生命周期在类外并不是很好的掌控&#xff0c;这样就很容易造成内存泄漏得到问题 比如以下代码&#xff1a; class Test { public: void foo(); pri…

C++中对多态的理解

1 多态&#xff1a;是指类中具有相似功能的不同函数&#xff0c;使用同一个名称来实现&#xff1b;是对类的行为再抽象&#xff1b;多态是通过重载函数和虚函数来实现的。 2 继承讨论的是类与类的层次关系&#xff0c;多态则是考虑在不同层次的类中&#xff0c;以及在同一个类…

C#.NET中的事件2

/** Created by SharpDevelop. * User: noo * Date: 2009-8-17 * Time: 15:34 * * 事件2 */usingSystem ;usingSystem .Windows .Forms ;classTest { staticvoidMain()//入口函数{ Form frmnewForm ();//新建一窗体frm.Text "我的窗体"; …

HTML学习之基础

HTML是网页的标记语言不是编程语言&#xff0c;有一些标记段组成。大小写不敏感&#xff0c;可以用常用的编辑器软件编写用浏览器打开即可 有不同的版本<!DOCTYPE html> <meta charset"utf-8">在<title>前为了能正常显示中文。 超链接&#xff1a;…

linux最基础的几个指令

cd 切换目录使用 pwd 显示当前目录路径 ls 列出目录内容 跟参数 -a 显示所有文件和目录 -A 显示所有文件包括隐藏-l 使用详细格式列出-d 显示目录名称而非内容-i 显示文件和目录的inode号-Z 显示文件和目录的上下文-R 子目录显示touch 创建文件或者改变文件时间 touch 2…

Advapi 登录类型8的错误

登录类型8&#xff1a;网络明文&#xff08;NetworkCleartext&#xff09; 这种登录表明这是一个像类型3一样的网络登录&#xff0c;但是这种登录的密码在网络上是通过明文传输的&#xff0c;WindowsServer服务是不允许通过明文验证连接到共享文件夹或打印机的&#xff0c;据我…

Varint

什么是Varint Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字&#xff0c;值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。 比如对于 int32 类型的数字&#xff0c;一般需要 4 个 byte 来表示。但是采用 Varint&#xff0c;对于很小的 …

Ubuntu 17.10安装Qt 5.10环境与Qt Creator 4.5开发工具(转自linux公社)

记录下在Ubuntu 17.10搭建Qt环境与安装Qt Creator开发工具的过程。机器装的Linux是Ubuntu 17.10&#xff0c;16.04与17.04的应该也相同。Qt 5.10和Qt 3D Studio发布 http://www.linuxidc.com/Linux/2017-12/149267.htm 1&#xff0c;Qt安装 1.1 下载Qt 这里提供Qt Creator的下…