精华内容
下载资源
问答
  • 自己理解的事务隔离性 事务四大特性: 原子性 一致性 持久性 隔离性 数据库的四种隔离级别: Serializable 序列化Repeatable read 可重复度Read committed 读提交Read uncommitted 读不提交(mysql) 这里先不...

    自己理解的事务隔离性

    事务四大特性: 原子性 一致性 持久性 隔离性

    数据库的四种隔离级别: 

    Serializable 序列化 Repeatable read 可重复度 Read committed 读提交 Read uncommitted 读不提交(mysql)

    这里先不说明这四个隔离级别是什么,先讨论一下由于数据库多任务同时操作数据产生的三种数据不一致的情况:

    1.脏读:指的是一个事务读取到另一个事务没有提交或者回滚(没有读到最终数据),造成的事务读取的数据与数据库数据不一致的情况。数据库解决方法,加上行锁。如图: 解决方法 使用一个事务无法读取到另一个事务未持久化的数据(这里用持久化,因为参考其他的博客,有的说是没有提交,有的说又进行了回滚,总之就是没有持久化,这一解决方法就是传说的Read Commend)

    2.不可重复读 :不可重复读 指的是一个事务在读取一个数据之后 其他事物对上一个事务读取的数据进行修改并提交,但是由于上一个事务的操作时间过长,导致该事务再次读取数据的时候读取的值前后不一致。这种情况虽然遵循了read commend (一个事务不能读取另一个事务未持久的数据,是的)但是还是发生了数据不一致。

    解决方案,规定一个事务A不能修改另一个事务B已读取的数据,此时事务B还在进行中。(repeatable read)

    3.幻读:在repeatable read隔离级别中,既然一个事务A无法修改事务B正在读取的数据,那事务A如果插入新的数据就不在repeatable read规定的范围内了吧,好。那就会发生事务A读取数据的数量是100 ,事务B插入了一条新的数据,结果实际数量是101,造成了事务A的两次读取数据的数量不一致,这就是幻读,解决方法 事务A对表操作时候其他事物无法对表进行操作 即加上表锁。传说中的serialable

     

    说明了这几种数据不一致的情况,现在还差read uncommend没有说了,就是没有任何控制。另外对下面的结果就很好理解了。

    展开全文
  • 数据库事务隔离级别总结

    万次阅读 多人点赞 2019-06-07 12:23:03
    学习数据库的时候常常会接触到事务, ACID等概念,那么到底什么是数据库事务数据库事务又具有哪些特点,和ACID有怎样的关系,事务隔离级别又是做什么的呢?。 事务及其四大特性? 事务(Transaction):访问并...

    学习数据库的时候常常会接触到事务, ACID等概念,那么到底什么是数据库的事务,数据库事务又具有哪些特点,和ACID有怎样的关系,事务的隔离级别又是做什么的呢?。

    事务及其四大特性?

    事务(Transaction):访问并可能更新数据库中各种数据项的一个程序执行单元(unit),它通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起。当在数据库中更改数据成功时,在事务中更改的数据便会提交,不再改变。否则,事务就取消或者回滚,更改无效。

    举个例子来说,张三给李四转了1000元钱,那么在数据库操作时,就要先把张三的账户减去1000元,再把李四的账户加上1000元,两部分操作放在一起,才是一个完整的转账过程,也可称之为事务。

    (1)原子性(Atomicity)

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

    就像你买东西要么交钱收货一起都执行,要么要是发不出货,就退钱。

    (2) 一致性(Consistency)

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

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

    打个比方,你买东西这个事情,是不影响其他人的。

    (3)隔离性(Isolation)

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

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

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

    (4)持久性(Durability)

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

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

    打个比方,你买东西的时候需要记录在账本上,即使老板忘记了那也有据可查。

    InnoDB引擎的事务实现

    InnoDB是mysql的一个存储引擎,大部分人对mysql都比较熟悉,这里简单介绍一下数据库事务实现的一些基本原理,在本地事务中,服务和资源在事务的包裹下可以看做是一体的。
    在这里插入图片描述
    而事务的ACID是通过InnoDB日志和锁来保证。事务的隔离性是通过数据库锁的机制实现的,持久性通过redo log(重做日志)来实现,原子性和一致性通过Undo log(回撤日志)来实现。Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了roll back语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。 和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将RedoLog持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是RedoLog已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态

    事务的隔离性及隔离级别

    以上介绍完事务的四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:
    在这里插入图片描述
    在这里插入图片描述
    3、幻读:一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。如果事务中都使用快照读,那么就不会产生幻读现象,但是快照读和当前读混用就会产生幻读。关于快照读与当前读可参见《InnoDB对MVCC的实现》

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

    “脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。数据库实现事务隔离的方式,基本上可分为以下两种:

    • 一种是在读取数据前,对其加锁,阻止其他事务对数据进行修改。
    • 另一种是不用加任何锁,通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本,因此,这种技术叫做数据多版本并发控制(MultiVersion Concurrency Control,简称MVCC或MCC),也经常称为多版本数据库。

    数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上 “串行化”进行,这显然与“并发”是矛盾的。同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。

    四种隔离级别

    为了解决“隔离”与“并发”的矛盾,ISO/ANSI SQL92定义了4个事务隔离级别,每个级别的隔离程度不同,允许出现的副作用也不同,应用可以根据自己的业务逻辑要求,通过选择不同的隔离级别来平衡 “隔离”与“并发”的矛盾。

    4个事务隔离级别:

    • Read uncommitted (读未提交):最低级别,以上问题均无法解决。
    • Read committed (读已提交):读已提交,可避免脏读情况发生。
    • Repeatable Read(可重复读):确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。
    • Serializable (串行化):最严格的事务隔离级别,要求所有事务被串行执行,不能并发执行,可避免脏读、不可重复读、幻读情况的发生。

    这四种隔离级别,分别有可能产生问题总结如下:
    在这里插入图片描述

    很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。避免不可重复读需要锁行(某一行在select操作时,不允许update与delete)就行,避免幻读则需要锁表。如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,幻读不能通过行锁来避免,需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题

    以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然隔离级别越高,越能保证数据的完整性和统一性,但是执行效率就越低,对并发性能的影响也越大。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况

    各类流行的数据库都实现了一些SQL标准中的事务隔离级别,但是他们的实现也是极其不一样的。Oracle仅仅实现了RC 和 SERIALIZABLE隔离级别。默认采用RC隔离级别,解决了脏读。但是允许不可重复读和幻读。其SERIALIZABLE则解决了脏读、不可重复读、幻读。MySQL支持全部4个隔离级别,但在具体实现时,有一些特点,比如在一些隔离级别下是采用MVCC一致性读,但某些情况下又不是。MySQL默认采用RR隔离级别,SQL标准是要求RR解决不可重复读的问题,但是因为MySQL通过nex-key lock在RR隔离级别下解决了幻读的问题。那么MySQL的SERIALIZABLE是怎么回事呢?MySQL的SERIALIZABLE采用了经典的实现方式,对读和写都加锁。

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

    select @@tx_isolation;
    

    在这里插入图片描述
    在MySQL数据库中设置事务的隔离级别:

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

    在这里插入图片描述

    互联网项目中MySQL用什么事务隔离级别

    Mysql默认的事务隔离级别是可重复读(Repeatable Read),那互联网项目中Mysql也是用默认隔离级别,不做修改么? OK,不是的,我们在项目中一般用读已提交(Read Commited)这个隔离级别! 居然是读已提交。

    我们先来思考一个问题,在Oracle、SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,为什么Mysql不选择读已提交(Read Commited)作为默认隔离级别,而选择可重复读(Repeatable Read)作为默认的隔离级别呢?

    我们先明白一点!项目中是不用读未提交(Read UnCommitted)和串行化(Serializable)两个隔离级别,原因有二: 采用读未提交(Read UnCommitted),一个事务读到另一个事务未提交读数据,这个不用多说吧,从逻辑上都说不过去!采用串行化(Serializable),每个次读操作都会加锁,快照读失效,一般是使用Mysql自带的分布式事务功能时才使用该隔离级别!也就是说,我们该纠结都只有一个问题,究竟隔离级别是用读已经提交呢还是可重复读? 接下来对这两种级别进行对比,讲讲我们为什么选读已提交(Read Commited)作为事务隔离级别!

    MySQL间隙锁

    当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(GAP LOCK)。举例来说,假如user表中只有101条记录,其empid的值分别是 1,2,…,100,101,下面的SQL:

    select * from  user where user_id > 100 for update;
    

    这是一个范围条件的检索且要求加上排他锁,InnoDB不仅会对符合条件的user_id值为101的记录加锁,也会对user_id大于101(这些记录并不存在)的“间隙”加锁。

    InnoDB使用间隙锁的目的,一方面是为了防止幻读(为了防止幻读去锁表则影响太大,会影响效率),以满足相关隔离级别的要求,对于上面的例子,要是不使用间隙锁,如果其他事务插入了user_id大于100的任何记录,那么本事务如果再次执行上述语句,就会发生幻读;另外一方面,是为了满足其恢复和复制的需要(发生幻读时的binlog,如果直接拿到备库去执行会发生了主备数据不一致的严重问题)

    很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这往往会造成严重的锁等待。因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件;当然,对一条不存在的记录加锁,也会有间隙锁的问题。

    间隙锁在InnoDB的唯一作用就是防止其它事务的插入操作,以此来达到防止幻读的发生,所以间隙锁不分什么共享锁与排它锁。如果InnoDB扫描的是一个主键、或是一个唯一索引的话,那InnoDB只会采用行锁方式来加锁,而不会使用Next-Key Lock的方式,也就是说不会对索引之间的间隙加锁。

    要禁止间隙锁的话,可以把隔离级别降为读已提交,或者开启参数innodb_locks_unsafe_for_binlog。

    RC与RR在锁方面的区别

    1、RR要用到间隙锁,而RC则没有间隙锁。因为MySQL的RR需要间隙锁来解决幻读问题。而RC隔离级别则是允许存在不可重复读和幻读的。所以RC的并发一般要好于RR;在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多;
    2、 RC 隔离级别,通过 where 条件过滤之后,不符合条件的记录上的行锁,会被释放掉,但是RR隔离级别,即使不符合where条件的记录,也不会释放行锁和间隙锁,所以从锁方面来看,RC的并发应该要好于RR;
    3、RC隔离级别时,事务中的每一条select语句会读取到他自己执行时已经提交了的记录,也就是每一条select都有自己的一致性读ReadView; 而RR隔离级别时,事务中的一致性读的ReadView是以第一条select语句的运行时,作为本事务的一致性读snapshot的建立时间点的,只能读取该时间点之前已经提交的数据

    展开全文
  • 事务四大特性(ACID) 1 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。 2 一致性...

    一、事务的四大特性(ACID)
    1  原子性(Atomicity)
    原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
    2  一致性(Consistency)
      一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
      拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
    3  隔离性(Isolation)
      隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
      即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
    4  持久性(Durability)
      持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
      例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。
      
    二、事务的隔离级别
    两个并发事务同时访问数据库表相同的行时,可能存在以下三个问题:
    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刚刚读取的记录,然后T1再次查询,发现与第一次读取的记录不同。
      不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
    3  幻读
      幻读是事务非独立执行时发生的一种现象。例如事务T1读取一条指定where条件的语句,返回结果集。此时事务T2插入一行新记录,恰好满足T1的where条件。然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这条新纪录就是幻想。
    幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

    事务隔离级别
    为了处理这些问题,SQL标准定义了以下几种事务隔离级别:

     

    READ_UNCOMMITTED 读未提交:最低级别,一个事务可以读取另一个未提交事务的数据。幻想读、不可重复读和脏读都允许。

     

    READ_COMMITTED 读已提交:一个事务要等另一个事务提交后才能读取数据。允许幻想读、不可重复读,不允许脏读。

    REPEATABLE_READ 可重复读:在开始读取数据(事务开启)时,不再允许修改操作。允许幻想读,不允许不可重复读和脏读。

    SERIALIZABLE 可串行化:最高级别,在该级别下,事务串行化顺序执行。幻想读、不可重复读和脏读都不允许。

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

     

     

     

    在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);

    而在Oracle数据库中,只支持Serializable (可串行化)和Read committed (读已提交)这两种级别,默认为Read committed级别。

     

     

    三、Spring五种事务隔离

     

     

    DEFAULT 使用数据库设置的隔离级别(默认),由 DBA 默认的设置来决定隔离级别;

    READ_UNCOMMITTED 会出现脏读、不可重复读、幻读(隔离级别最低,并发性能高);

    READ_COMMITTED  会出现不可重复读、幻读问题(锁定正在读取的行);

    REPEATABLE_READ 会出幻读(锁定所读取的所有行);

    SERIALIZABLE 保证所有的情况不会发生(锁表)。
     

    四、Spring七个事务传播行为

    在TransactionDefinition接口中定义了七个事务传播行为:

    PROPAGATION_REQUIRED  如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。这是Spring默认的传播行为。

    PROPAGATION_SUPPORTS  如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。

    PROPAGATION_MANDATORY  如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

    PROPAGATION_REQUIRES_NEW  总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

    PROPAGATION_NOT_SUPPORTED  总是非事务地执行,并挂起任何存在的事务。

     

    PROPAGATION_NEVER  总是非事务地执行,如果存在一个活动事务,则抛出异常。

     

    PROPAGATION_NESTED  如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

     

     

    展开全文
  • 数据库四大特性和事务隔离级别 数据库中经常被问到四大特性和隔离级别,一般都是涉及到概念性问题,在此做一些整理总结,方便理解。 1、事务的隔离级别 由低到高依次为Read uncommitted(未授权读取、读未提交)...

    数据库四大特性和事务隔离级别

    数据库中经常被问到四大特性和隔离级别,一般都是涉及到概念性问题,在此做一些整理总结,方便理解。

    1、事务的隔离级别

    由低到高依次为Read uncommitted(未授权读取、读未提交)、Read committed(授权读取、读提交)、Repeatable read(可重复读取)、Serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

    (1)Read uncommitted(未授权读取、读未提交):

    1)其他事务读未提交数据,出现脏读;
    2)如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
    3)避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。
    (读未提交:一个事务写数据时,只允许其他事务对这行数据进行读,所以会出现脏读,事务T1读取T2未提交的数据)

    (2)Read committed(授权读取、读提交):

    1)允许写事务,所以会出现不可重复读
    2)读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
    3)该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
    (读已提交:读取数据的事务允许其他事务进行操作,避免了脏读,但是会出现不可重复读,事务T1读取数据,T2紧接着更新数据并提交数据,事务T1再次读取数据的时候,和第一次读的不一样。即虚读)

    (3)Repeatable read(可重复读取):

    1)禁止写事务;
    2)读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
    3)避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。
    (可重复读:读事务会禁止所有的写事务,但是允许读事务,避免了不可重复读和脏读,但是会出现幻读,即第二次查询数据时会包含第一次查询中未出现的数据)

    (4)Serializable(序列化):

    1)禁止任何事务,一个一个进行;
    2)提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
    3)序列化是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。

    2、出现的问题:

    当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题:脏读、不可重复读、幻读。

    (1)脏读

    1.脏读定义:

    1)说法1:指在一个事务处理过程里读取了另一个未提交的事务中的数据,读取数据不一致。
      2)说法2:指事务A对数据进行增删改操作,但未提交,另一事务B可以读取到未提交的数据。如果事务A这时候回滚了,则第二个事务B读取的即为脏数据。

    2.举例:

    当一个事务正在多次修改某个数据,而在这个事务中多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。
    例如:用户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)不可重复读

    1.不可重复读定义:

    1)说法1:是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
      2)说法2:一个事务A中发生了两次读操作,第一次读操作和第二次读操作之间,另一个事务B对数据进行了修改,这时两个事务读取的数据不一致。

    2.举例:

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

    3.不可重复读和脏读的区别:

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

    (3)虚读(幻读)

    1.幻读定义:

    1)说法1:是事务非独立执行时发生的一种现象。
      2)说法2:第一个事务A对一定范围的数据进行批量修改,第二个事务B在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。

    2.举例:

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

    3.幻读和不可重复读区别:

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

    3、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级别。
    1)在MySQL数据库中查看当前事务的隔离级别:

    select @@tx_isolation;
    

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

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

    例1:查看隔离级别:

    查看当前事务的隔离级别

    查看当前事务的隔离级别


    例2:将事务的隔离级别设置为(Repatable read)可重复读或者Read uncommitted级别:
    设置隔离级别(1)

    设置隔离级别(1)

    或者
    设置隔离级别(2)

    设置隔离级别(2)

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

    Connection对象的字段

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

    JDBC设置隔离级别

     

    4、事务的四大特性

    数据库中事务的四大特性(ACID):原子性、一致性、隔离性、持久性。如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:

    (1)原子性(Atomicity)

    原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。

    (2)一致性(Consistency)

    一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
      如:拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。

    (3)隔离性(Isolation)

    隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
      即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

    (4)持久性(Durability)

    持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
      例如:我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。

    后记:其实说来说去也就三方面的概念
    1)四大隔离级别:串行化、可重复读、读已提交、读未提交;
    2)四大特性(ACID):原子性、一致性、隔离性、持久性;
    3)三个问题:脏读、不可重复度、幻读;

    展开全文
  • 介绍完事务四大特性(简称ACID),现在重点来说明下事务的隔离性,当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,...
  • 数据库四大特性和事务隔离级别 数据库中经常被问到四大特性和隔离级别,一般都是涉及到概念性问题,在此做一些整理总结,方便理解。 1、事务的隔离级别 由低到高依次为Read uncommitted(未授权读取、读未提交)、Read...
  • 学习数据库的时候常常会接触到事务, ACID等概念,那么到底什么是数据库事务数据库事务又具有哪些特点,和ACID有怎样的关系,事务隔离级别又是做什么的呢?。 事务及其四大特性? 事务(Transaction):访问并...
  • 学习数据库四大特性及事务隔离级别 一丶事务ACID四大特性  A(原子性Atomicity) :  事务是数据库的逻辑工作单位,事务里所有的操作要么全做,要么不做.  C(一致性Consistency):  事务执行的结果必须使数据库从...
  • 数据库事务四大特性以及事务隔离级别解释  本篇讲诉数据库事务四大特性(ACID),并且将会详细地说明事务隔离级别。 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性...
  • 数据库事务隔离级别 数据库事务 事务四大特性(ACID) 事务四大特性包括原子性、一致性、隔离性、持久性。 原子性 (Atomicity) 原子性指:事务所包含的操作要么全部成功,要么全部失败,成功将数据...
  • 在我们了解数据库隔离级别前先来回顾一下数据库读数据时可能遇到的问题: (1)脏读 一个事务对数据进行更新操作,但还完成,此时另一事务读取该数据,如果此时第一个事务由于操作失败进行了回滚,那么此时另外...
  • 四大特性ACID原子性(Atomicity)原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。失败回滚的操作事务,将不能对数据库有任何影响一致性(Consistency)一致性是指事务必须使数据库从一个一致性状态变换到...
  • 首先讲概念 数据库隔离级别 四大特性或者脏读重复读幻读 这些名词 都是简称,都需要加上事务两个字。这个事务跟写代码的那个事务是同一个东西。 如果没有数据库事务的概念。会出现很多问题。那究竟啥事数据库事务 ...
  • 事务四大特性ACID如果没有事务隔离会出现什么问题1.脏读(Dirty Read)2.不可重复读(Unrepeatable Read)3.幻读(Phantom Problem)事务的隔离级别1.读未提交(Read Uncommitted)2.读提交(Read Committed)3.可重复读...
  • 数据库事务隔离级别四大特性 - 四大特性 (1)原子性(Atomicity) 原子性指的是事务操作要么全部成功,要么全部回滚。简单的来说就是操作成功,就完全应用到数据库中;操作失败,则不影响到数据库中的数据。 (2)...
  • 本篇讲诉数据库事务四大特性(ACID),并且将会详细地说明事务隔离级别。 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么...
  • 今天来聊一聊数据库事务隔离级别问题,之前一直模糊不清,找个时间整理清楚。 数据库事务四大属性(ACID特性): 原子性(atomicity) 一个事务是不可分割的一部分,要么都做,要么都不做; 一致性(consistency)...
  • 四大隔离级别4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。1 SERIALIZABLE(串行化...
  • 数据库事务四大特性(ACID): 原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态...
  • 数据库 四大隔离级别

    2021-02-24 22:45:57
    数据库事务隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable。 在事务的并发操作中可能会出现脏读,不可重复读,幻读 脏读:指当一个事务正在访问数据,并且对...
  • 数据库事务 四大特性 原子性 隔离性 持久性 一致性 原子性 一个事务的多个数据库操作是一个不可分割的原子单元,只有所有的操作执行...事务之间有一定的隔离级别,保障不同程度的数据一致性。 持久性 一旦事务提交成...
  • 数据库事务必须具备四大特性,简称ACID特性 所谓的事务,是操作的整体性, (1)原子性(atomicity) (2)一致性 (3)隔离性 (4)持久性 事物隔离级别: 1,读未提及(read-uncommit) 隔离级别最低,允许脏...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,486
精华内容 594
关键字:

数据库四大事务隔离级别