我理解的数据库事务

一、最简单的例子来说明事务

“A账户向B账号汇钱”来说明事务

1、从A账号中把余额读出来。
2、对A账号做减法操作。
3、把结果写回A账号中。
4、从B账号中把余额读出来。
5、对B账号做加法操作。
6、把结果写回B账号中。

为了数据的一致性,这6件事,要么都成功做完,要么都不成功。而且这个操作的过程中。对A、B找好的其他访问必须锁死,所谓锁死就是要排除其他的读写操作,不然会有脏数据问题,这就是事务。

二、数据库事务特性

  • Atomic(原子性)

    事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。事务的原子性也体现在事务对数据的读取上,例如一个事务对同一数据项的多次读取的结果一定是相同的。

  • Consistency(一致性)

    只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初的状态。
    事务需要保持数据库的正确性、完整性和一致性。
    有些时候这种一致性由数据库的内部规则保证,例如数据的类型必须正确,数据值必须在规定的范围内,等等。
    另外一些时候这种一致性由应用保证的,例如, 一般情况下银行账务余额不能是负数,信用卡消费不能超过该卡的信用额度等。

  • Isolation(隔离性)

    事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。
    同时,并行事务的修改必须与其他并行事务的修改相互独立。
    事务的隔离性一般由事务的锁来进行控制。

    许多时候数据库在并发执行多个事务,每个事务可能需要对多个表进行修改和查询,与此同时,更多的查询请求可能要在执行。数据库需要保证每一个事务在它的修改全部完成之前,对其他的事务是不可见的。

    换句话说,不能让其他事务看到该事务的中间状态,例如,从银行账户A转一比款项a到账户B,不能让其他事务(例如账户查询)看到A账户已经扣除款项a但B账户却没有增加款项a的状态。

  • Durability(持久性)

    事务结束后,事务处理的结果必须能够得到固化,即使系统出现各种异常也是如此。

三、数据库的隔离级别

由于性能的考虑,许多数据库允许使用牺牲隔离属性来换取并发度,从而获取性能的提升。

  • Read uncommitted(RU):读取未提交的数据(未授权读取),即其他事务已经修改单未commit的数据,这是最低的隔离级别。允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
  • Read committed(RC):允许不可重复读取,在一个事务中,对同一个项,前面的读取跟后面的读取结果可能不一样。例如第一次读取时另一个事务的修改还没有提交,第二次读取时已经提交了。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
  • Repeatable read(RR):可重复读取,在一个事务中,对同一个项,前面的读取跟后面的读取结果一样。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
  • Serializable(S):可序列化,即数据库的事务市可串行化执行的,就像一个事务执行的时候没有别的事务同时在执行,这是最高的隔离级别。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别的降低可能导致读取到脏数据或事务执行异常

  • Lost update(LU) :两个事务同时修改一个数据项,但后一个事务中途失败退出,则对数据项的两个修改可能都丢失。
  • Dirty Reads(DR): 一个事务读取某数据项,但另一个事务更新了此数据项却没有提交,这样所有的操作可能都得回滚。
  • Non-repeatable Reads(BRR):一个事务对同一数据项的多次读取可能得到不同的结果。
  • Second lost updates problem(SLU):无法重复读取的特例,两个并发事务同时读取和修改同一数据项,则后面的修改可能使得前面的修改失效。
  • Phantom Reads(PR):也称为幻读,例如在事务执行过程中,由于前面的查询和后面的查询的期间有另外一个事务插入数据,后面的查询结果中未出现的数据。

隔离级别与读写异常(不一致)的关系如下

  LU DR NRR SLU PR
RU Y Y Y Y Y
RC N N Y Y Y
RR N N N N Y
S N N N N N

四、数据库的事务与线程相似的地方

  • 线程之间共享同一片资源,而事务共享的则是数据库内部的数据
  • 多线程的意义在于并发执行,提高效率;事务并发执行也能提高程序与数据库交互的效率。

五、用例子来说明事务隔离性

假设账户A有1000元,B有1000元,C有1000A

1、操作员u1执行一次转账事务m1
从A转移500元到B,再从A的余额中转移50%元平均分配到 A B C D E余额中

2、操作员u2执行一次转账事务m2
从B转移1000元到A

3、操作员u3执行一次转账事务m3
从A转移200元到B

4、操作员u4开户D

账户表为T_C,其包含字段为 账户名称cname 余额money

记录为{A,1000},{B,1000}

事务m1的操作包括

  读A,读B,
  写A,写B,
  提交AB,读A,
  读C,写C,写C,
  提交AC

事务m2的操作包括

  读B,读A,
  写B,写A,
  提交AB

事务m3的操作包括

    读A,读B,
    写A,写B,
    提交AB

事务m4的操作包括

    写D,
    提交D

1.若未授权读取ReadUncommitted

m1读A,B,写了A但没写B
此时m2不可以写B,可以读取AB,但是B是脏读。
隔离级别使用了“排他写锁”。

2.若授权读取ReadCommitted

m1读A,B,写了A但没写B
此时m2不可以写B,可以读取A,不能读取B,因为B是脏读。
隔离级别使用了“排他写锁”。
m1读写了A,B,提交A``B,
m3提交了A``B 此时m1准备第二次A是允许的。
隔离级别使用了“瞬间共享读锁”。
(但由于第二次读产生了不可重复读的问题,事务1脱力了元自行,因为逻辑上看事务1中被插入了3,影响了A的余额50%的计算。)

3.若可重复读取RepeatableRead

m1读A,B,写了A
但没写B此时m2不可以写B,可以读取A,不能读取B,因为B是脏读。
隔离级别使用了“排他写锁”。
m1读写了A,B,提交A``B,
m4提交了D此时m3是能读不能写A并更新提交的。
此时m4是能读能能插入D的。隔离级别使用了“共享读锁”。
(和ReadCommitted比RepeatableRead区别对已经提交的事务可以进行读,但不能写,但是同一张表可以插入新的记录。)

4.序列化Serializable

任何事务都只能等前一事务完全执行完再执行。 但是失去了并发性。

转载,有修改,我只是个搬运工

时间: 2025-01-14 09:29:23

我理解的数据库事务的相关文章

数据库:自己理解的“数据库事务隔离级别”

转载请注明出处: jiq?钦's technical Blog - 季义钦 引言:在网上搜了很多关于事务的文章,感觉单独来看都很难看懂,所以综合自己的理解写一篇我自己能理解的关于关系型数据库事务的文章. 一.事务特征 我们都知道数据库事务具备ACID特性: Atomic(原子性):一个事务要么成功,要么失败 Consistency(一致性):一致性代表了底层数据存储的完整性.事务执行前后数据库都必须处于一个合法的状态.什么才是一个合法的状态? 比如满足数据库的唯一性约束.数据类型验证.引用完整性

[MySQL]对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解与数据库事务隔离级别 - 分析脏读 & 不可重复读 & 幻读

刚开始写博客.. 写的太low. 1.数据库的两种读,每种读读的数据版本不一样,所以也称为MVCC,即多版本并发控制 a) 快照读 select * from where xxx  这种形式的都是快照读. b) 当前读 update , insert ,delete ,select xx from xx for update ,  in share mode 都是当前读 当前读会等待,不会返回数据的历史版本 2.mvcc 的实现原理 mvcc是基于read view.活跃事务列表 做的,以后的文

理解数据库事务隔离级别以及脏读, 不可重复读, 幻读(转)

  转自:http://blog.csdn.net/sunxing007/article/details/6427290 数据库事务的4个特性: 原子性(atomic): 都成功或者都失败: 一致性(consistency):事务操作之后,数据库所处的状态和业务规则是一致的;比如a,b账户相互转账之后,总金额不变: 隔离性(isolation):操作中的事务不相互影响; 持久性(durability):事务提交后被持久化到数据库. 脏读,不可重复读, 幻读 幻读phantom read:事务1读

关于数据库事务中脏读、不可重复读和幻读的理解

数据库有四种隔离级别,分别是: SOLATION_READ_UNCOMMITTED:允许读取改变了的还未提交的数据,可能导致脏读.不可重复读和幻读. ISOLATION_READ COMMITTED:允许并发事务提交之后读取,可以避免脏读,可能导致重复读和幻读. ISOLATION_REPEATABLE_READ:对相同字段的多次读取结果一致,可导致幻读. ISOLATION_SERIALIZABLE:完全服从ACID的原则,确保不发生脏读.不可重复读和幻读. 四种不同的隔离级别代表着数据库对资

彻底理解数据库事务

事务 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).在计算机术语中,事务通常就是指数据库事务. 概念 一个数据库事务通常包含对数据库进行读或写的一个操作序列.它的存在包含有以下两个目的: 1.为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法.2.当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰.

关于数据库事务、隔离级别、锁的理解与整理(转)

数据库事务的ACID特性 1. 事务的四个特性 数据库事务(Transaction)是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行.一方面,当多个应用程序并发访问数据库时,事务可以在应用程序间提供一个隔离方法,防止互相干扰.另一方面,事务为数据库操作序列提供了一个从失败恢复正常的方法. 事务具有四个特性:原子性(Atomicity).一致性(Consistency).隔离型(Isolation).持久性(Durability),简称ACID. 1.1 原子性(Atom

关系型数据库事务遵循的原则

事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性: 1.A (Atomicity) 原子性 原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚. 比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元:2)存入100元至B账户.这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元. 2.C (Consi

(转)对SQLSERVER数据库事务日志的疑问

本文转载自桦仔的博客http://www.cnblogs.com/lyhabc/archive/2013/06/10/3130856.html 对SQLSERVER数据库事务日志的疑问 摸不透SQLSERVER了 实验环境:SQLSERVER2005 SP4,Windows7 本来没什么心情写文章,反正没人看,关于我文章中提到的问题,有些可以从文章结尾的MSDN补充那里找到答案,而有些还没有答案 根据CSDN博客的这篇文章介绍,大家可以先看一下,然后再继续往下看,因为下面会引用到CSDN博客里的

PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(3)

2.3 理解一致性和数据丢失 挖掘PostgreSQL事务日志而不考虑一致性是不可能的.在本章的第一部分,我们已经大体上解释了事务日志的基本思想.您已经知道,无需事先的日志改变的能力,使数据处于一种好的形状是很难甚至是不可能的. 到现在为止,我们大多都在讨论崩溃的问题.因为数据文件中的条目的损坏而丢失文件是绝对不好的.但是,崩溃不是您要关心的唯一问题.另外两个重要的主题是: • 性能 • 数据丢失 虽然这可能是一个重要的主题的明显的选择,我们有这样的感觉,这两个主题都不好理解,是受尊敬的,并因此