事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢失问题

事务的4个特性——ACID(原子性、一致性、隔离性和持久性)



事务是一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。事务通常以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK操作结束,COMMIT即提交,提交事务中所有的操作、事务正常结束。ROLLBACK即回滚,撤消已做的所有操作,回滚到事务开始时的状态。

对于事务可以举一个简单的例子:转账,有A和B两个用户,A用户转100到B用户,如下所示:

A:---->支出100,则 A-100

B:---->收到100,则 B+100

A--->B转账,对应如下SQL语句:

UPDATE  ACCOUNT SET MONEY=MONEY - 100 WHERE NAME='A';

UPDATE  ACCOUNT SET MONEY=MONEY + 100 WHERE NAME='B';

事务有4个特性,一般都称之为ACID特性,简单记为原一隔持(谐音:愿意各吃,即愿意各吃各的),如下表所示:

事务是指对系统进行的一组操作,为了保证系统的完整性,事务需要具有ACID特性,具体如下:
1. 原子性(Atomicity
     一个事务包含多个操作,这些操作要么全部执行,要么全都不执行。实现事务的原子性,要支持回滚操作,在某个操作失败后,回滚到事务执行之前的状态。
     回滚实际上是一个比较高层抽象的概念,大多数DB在实现事务时,是在事务操作的数据快照上进行的(比如,MVCC),并不修改实际的数据,如果有错并不会提交,所以很自然的支持回滚。
     而在其他支持简单事务的系统中,不会在快照上更新,而直接操作实际数据。可以先预演一边所有要执行的操作,如果失败则这些操作不会被执行,通过这种方式很简单的实现了原子性。
2. 一致性(Consistency)
     一致性是指事务使得系统从一个一致的状态转换到另一个一致状态。事务的一致性决定了一个系统设计和实现的复杂度。事务可以不同程度的一致性:
     强一致性:读操作可以立即读到提交的更新操作。
     弱一致性:提交的更新操作,不一定立即会被读操作读到,此种情况会存在一个不一致窗口,指的是读操作可以读到最新值的一段时间。
     最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有错误发生,不一致窗口的大小依赖于:通信延迟,系统负载等。
     其他一致性变体还有:
     单调一致性:如果一个进程已经读到一个值,那么后续不会读到更早的值。
     会话一致性:保证客户端和服务器交互的会话过程中,读操作可以读到更新操作后的最新值。
3. 隔离性(Isolation)
     并发事务之间互相影响的程度,比如一个事务会不会读取到另一个未提交的事务修改的数据。在事务并发操作时,可能出现的问题有:
     脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败,事务B读到的就是脏数据。
     不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。
     幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。
     事务的隔离级别从低到高有:
     Read Uncommitted:最低的隔离级别,什么都不需要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
     Read Committed:只有在事务提交后,其更新结果才会被其他事务看见。可以解决脏读问题。
     Repeated Read:在一个事务中,对于同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不可重复读。
     Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。可以解决并发事务的所有问题。
     通常,在工程实践中,为了性能的考虑会对隔离性进行折中。
4. 持久性(Durability)
     事务提交后,对系统的影响是永久的。




更新丢失问题

   

 

    

 

 

    

 

 

 

 

 

 

 

 

   

 

    

   

 

                         

               

    

                         

 

 

           

 

 

 

 

  

    



 




 


 

       
      


 

      
  
         
   

 



    

 

 

 
 

 

  1.      
  2.                  
  3.                 
  4.                   
  5.       
  6.        
  7.   
  8.       
  9.        
  10.       
  11.       
  12.   
  13.      
  14.             
  15.          

    

    

       
 

 

 

 

 

 

 

>

>

>

>

>
>
>

 

 

 

 

 

 

>

>



 



    

时间: 2024-08-01 15:49:24

事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢失问题的相关文章

SQL Server中事务复制造成更新丢失的解决方法

造成更新丢失的常见情况有三种: 1.发布数据库启用了read_committed_http://www.aliyun.com/zixun/aggregation/11220.html">snapshot隔离级别可能导致分发代理报20598错.我们可以通过检查发布数据库的隔离级别属性是否为read_committed_snapshot判断这种问题的可能性. use <pubdb> go dbcc useroptions go 2.订阅方手动改变数据 3.外键或触发器的"

HIVE 新特性 ACID 初试

在 Hive 0.14 之前,Hive QL 一直不支持insert.update.delete 操作,这显然很不方便,尤其是在构建数据仓库的过程中,一个比较常见的例子是维度表经常需要更新某列,在 Hive 中需要更新历史所有数据,这显然是不合理的. 在 Hive 0.14 版本,支持了行级别的 ACID 与 Transactions,这也就解决了上面的问题. 本文主要讲解如何在 Hive 0.14 配置,使得支持上述两个特性,相关原理及性能分析后面再单独写一篇文章来分析. 相关软件说明: Hi

数据库中事务的隔离性

在标准SQL规范中,定义了四个事务隔离级别. 1.读未提交 read uncommitted. 可以读到数据在别的事务处理期间的所有可能值. 2.读已提交 read committed. 别的事务已提交的值都可以被读到. 3.可重复读 repeatable read. 只能读到该事务开始前的值.忽略其他事务的修改. 4.串行化 serializable. 是最严格的事务隔离级别,它要求所有的事务都被串行执行. 5.例子 为了方便说明问题,定义事务A:不断的读小明的语文成绩.事务B:将小明的语文成

thrift 一个有意思的特性:Class名称无关性

最近开发的一个项目,后端采用thrift框架来提供rpc服务(java语言实现),然后前端采用php语言来生成thrift client调用后台RPC服务.由于某些原因,上周我把thrift定义文件中一个struct名称修改了,当然也没多想,顺手就把java服务端重新编译部署,而php前端的部署未做任何变化,按常规理解,服务契约中的类名,从A改成B,服务的调用方理应同步更新部署,否则感觉应该会出错. 然而,美好的事情就这么发生了,一切运行正常,依旧丝丝顺滑! 再然后,我就开始思考人生,重新理解

NewSQL数据库简介

NewSQL数据库简介 NewSQL的未来 原创 2016-10-20 黄编者按:黄东旭,PingCAP 联合创始人.CTO,是很多人仰望的国内分布式存储领域(NewSQL) 技术大神级别的人物.我们请黄东旭来聊聊他眼中的NewSQL,有需要交流的内容,欢迎留言. 最近数据库圈的一个比较大的事件是 NoSQL 先驱之一的 RethinkDB 的关张大吉,RethinkDB这个事情本身我就不多做评论了,现在这个时机去分析不免有马后炮的嫌疑,今天我想借着这个引子谈谈新型数据库的未来.   纵观过去十

oracle多用户并发及事务处理

多用户并发访问 事务:作用于某些数据的一个不可分割的操作 锁:写锁.互斥锁(仅能被一个进程使用) 读锁.共享锁(可被多个进程使用) 更新丢失 脏读 不可重复读 幻影读 隔离级别: 1 READ COMMITTED 每个语句得到完整的视图 2 SERIALIZABLE 事务级别实施串行化 Oracle并发特性 1 回滚段:存储"撤销"信息的数据结构 redo日志用来记录数据库的所有事务:回滚段用于提供事务回滚和读一致性 2 系统改变号 SCN:保证事务执行的顺序 3 数据块中的锁:每个锁

《解读NoSQL》——2.5 比较ACID和BASE——两种可靠的数据库事务方法

2.5 比较ACID和BASE--两种可靠的数据库事务方法 兼顾性能和一致性的事务控制在分布式计算环境下是很重要的.通常会在两种事务控制模型中选择其一使用:ACID用于RDBMS,BASE用在很多NoSQL系统.即使数据库事务只有很少一部分需要事务完整性,但了解RDBMS和NoSQL系统能够采用这些事务控制策略也是很重要的.这两种模型的区别在于应用开发人员所付出的努力和事务控制所发生的位置(层级). 让我们从一个简单的银行业务案例来展现一个可靠的事务.如今,许多人都有两个银行账户:储蓄账户和支票

RocksDB事务实现TransactionDB分析

基本概念 1. LSN (log sequence number) RocksDB中的每一条记录(KeyValue)都有一个LogSequenceNumber(后面统称lsn),从最初的0开始,每次写入加1.该值为逻辑量,区别于InnoDB的lsn为redo log物理写入字节量. 这个lsn在RocksDB内部的memtable中是单调递增的,在WriteAheadLog(WAL)中以WriteBatch为单位递增(count(batch.records)为单位). WriteBatch是一次

数据库事务

数据|数据库 关于事务的隔离性 例如:统计定单系统中事务活动 如下1.事务T1打印定单表中的记录2.T2向定单表插入了新的定单,T2提交3.事务T1统计定单表中的的记录总数,T1提交 因为事务T2在T1结束前向定单表中插入了新的记录,导致事务T1打印的定单记录数量和T1统计的定单数量不一致.  产生并发异常问题的主要原因是并发操作破坏了事务的隔离性,导致数据不一致.如何使一个事务不受到其它事务的干扰,保证数据一致性???完整的例子代码,在线等待,谢谢大家的关心:) 事务事务是作为单个逻辑工作单元