一、事务的基本概念

所有文章

https://www.cnblogs.com/lay2017/p/12078232.html

正文

一、什么是事务?

概念性的东西通常都显得抽象、晦涩,包罗万象但似乎很难一下子抓到要点。为此,我们先来看一个比较典型的例子:银行转账

  市民王先生到银行转账1000元给老李,王先生的账户里现有10000元,老李的账户恰好也有10000元。银行将从王先生账户扣除1000元:10000-1000=9000,然后给老李的账户加上1000元:10000+1000=11000。

  王先生的账户剩余:9000元

  老李的账户剩余:11000元

  我们来看看,这里有两个步骤1)从王先生账户扣钱;2)给老李账户加钱;我们做一个问题假设,银行柜员从王先生的账户扣完钱以后,忘记给老李的账户加钱了。那么会出现什么结果?

  王先生的账户剩余:10000-1000=9000

  老李的账户剩余:10000+0=10000

  很明显,老李没有收到王先生的钱。而王先生也很委屈,已经扣完钱了啊。这反应了一个比较严重的问题,就是当你要处理的事情被分为了很多个步骤,这些步骤可能处理成功,可能失败,甚至可能完全忘了处理。如果都处理成功也没什么问题。如果都处理失败,我们也可以当作什么都没有发生过。唯独有的步骤成功,有的步骤失败的时候比较烦人了。就会出现上面的例子中的问题。

  这时候我们会想,既然都成功或者都失败都行,我们能不能让多个步骤的处理像处理一个步骤一样简单点要么全部成功,要么全部失败呢?如上例子中,要么王先生扣完1000以后也给老李加上10000,要么王先生没扣钱,老李也没加钱,最多老李发现钱没到账会再要求王先生转一次。

  我们可以给这两个步骤取个名字:转账,转账包含了从一个账户扣钱,给另一个账户加钱两个步骤,两个步骤同时成功或者同时失败。

  抛开上面的例子,我们所要处理的其它事情会不会也存在转账这样的问题呢?当然!那么,我们把这些要做的事情像转账一样取个共同的名字,就叫做"事务"。

  到这里,我们给事务下一个定义吧。

事务就是你要做的事情,通常这件事会包含多个步骤。事务中的多个步骤处理起来就像处理一个步骤一样,要么全部成功,要么全部失败。事务解决了多个步骤部分成功,部分失败所带来的不一致问题。

所以,事务的诞生是其实是为了解决问题,这种技术手段解决了"一致性"问题。

二、事务的ACID四个特征

任何存在的真实的亦或者是虚拟的人事物都有其特征,我们通过其特征来识别它与其它人事物之间的区别。

那么,事务这种技术手段存在什么特征呢?

事务的特征,我们简称为ACID。它们分别是什么呢?

A:atomicity 原子性

C:consistency 一致性

I:isolation 隔离性

D:durability 持久性

一致性

我们总说事务具备一致性,但是个人认为它并非事务本身的特性。而是事务这种技术手段,维护了所要处理的对象的一致性。比如说mysql中的数据的一致性,mysql的事务技术维护了mysql内部存储的数据具备一致性。

再来,理解一致性,我们先提一下我们以前热力学学过的"能量守恒定律"。

能量守恒定律是指一个封闭或者孤立的系统中总的能量是保持不变的。不会凭空产生,也不会凭空消失,只能从一个物体传递给另一个物体,且能量的形式可以相互转换。

和我们赖以生存的自然界一样,我们程序员所构建的系统也是一个"能量守恒"的世界。我们的代码,我们的数据都是这个世界的一尘一土。

而事务技术,就是为了让这个程序世界能够像真实世界一样做到"能量守恒"。我们简称其为"事务的一致性"。

似乎从这里感受到了早年看书经常忽略的话"编程就是对现实世界进行建模",我们可以像上帝一样在这里创造万物,而万物生生不息。

原子性

原子是什么?原子是指在化学的定义上一个不可再分割的基本微粒,它是构成一般物质的最小单元,我们也成为元素。

以上定义指的是一个客观存在的事物由原子构成。那,如果是一个行为,它具备原子特性是什么概念呢?

首先,原子不可分割,是最小的单元。所以,一个行为具备原子特性就不能被再拆分成多个步骤,我们把这个步骤看成一个最小单元。行为全部完成,或全部没开始。还是不好理解对吧?我们举个例子

你一步一步地走路回家,一路上你不停地抬脚、落脚。这时候你突然发现在你正要落脚地位置有一坨不可言状地东西。你感到恶心,所以脚落到一半就收住了。

很明显,抬脚和落脚这两个行为并没有形成"走一步"地原子性。想象一下,如果抬脚和落脚这两个行为成为了一个行为一样,抬了就必定会落,那么即使你的大脑发现有一坨东西,为了"走一步"你也要踩下去,因为抬脚和落脚是原子行为,不可分割。

当然,我们可以抬脚以后收回,这就是事务"回滚",让一切像没发生过一样重新开始。

这里的原子性只是表达了事务的一种特性,它旨在忽略你要做的事情的具体步骤。保证事情全部完成,或者全部像没开始一样。

持久性

持久性在定义中是指:事务一旦被提交,它产生的改变就是永久性的。即使发生故障也不应该影响改变的成功与否。

这里注意"提交"这两个事情,我们通俗地说就是一件事完成以后,它产生的影响就是既存事实。不能因为其它因素导致这个事实不存在了。好像还是不好理解,举例说明

银行查账的时候发现,A转账给B,B转账给C。这里有两个转账事务产生了。那么如果银行因为停电,A转账给B这个事务不再是既存事实,银行查账只发现B转账给C这一笔,就会奇怪为什么B的账户了多了一笔本该是A转账过来的钱呢?

持久性,代表了一种不可改变的既存事实,也就是我们常说的历史无法改变,只能看向未来。这样看来,事务的持久性是不是也意味着在维护着上面的"一致性"呢?即,如果丢了秦始皇统一的历史,整个后面的朝代还怎么存在呢

隔离性

我们先来回顾一下前面的原子性,一件事要么处于所有步骤完成的状态,要么处于所有步骤未开始的状态。这很好的保证了在一件事务发生的时候,世界的"能量守恒"的基础。

那,如果多个事务同时发生的时候呢?是不是依旧会出现各种错误?隔离级别,我们以数据库的角度或许更好理解一点。

比如,数据库记录着字段:a=0,b=0

事务A将a=1,事务B检查a=1,则将b=1

1)read uncommitted级别

A将a=1,未提交事务。B检查a=1,将b=1,提交事务。A回滚a=0。

这时候b产生了错误结果。这就是脏读,读取了未提交的数据。

所以,如果A修改a的,B修改b不依赖于a的结果,那么可以采用read uncommitted级别。简单来说,A和B本身就不需要考虑并发。

2)readcommitted级别

A将a=1,未提交事务。B检查a=0,不处理b,提交事务。A回滚a=0。

这时候b=0,a=0,数据并没有异常。

再来,A将a=1,未提交事务。B检查a=0,不处理b。A提交事务,B再次查询a并打印日志a=1。

这时候,a=1,b=0,日志a=1。在B事务中a的值前后不一致。这就是不可重复读问题。

readcommitted其实就是在数据库进行update操作的时候,read需要等待update的事务提交以后才能读取。

3)repeatable read级别

A将a=1,未提交事务。B检查a=1,不处理b。A提交事务,B再次查询a并打印日志a=0。

这时候,a=1,b=0,日志a=0。在B事务中a的值前后一致了。

repeatable read其实就是在事务开启的时候,不允许其它事务进行update。但是如果是insert操作呢?所以,如果出现insert操作,则又会有幻读问题。

4)serializable级别

A将a=1,提交事务。B检查a=1,处理b=1,提交事务。

这时候a=1,b=1。A和B事务串行化处理了,简单来说就是单线程的节奏。所以,可以想象serializable这个级别的效率有多低下。

不过,如果不考虑效率问题,serializable会是解决脏读、不可重复读,幻读的最简单的方案了。

总结

本文简单叙述了事务的基本概念,并讨论了ACID的特性。比较麻烦的其实是事务的隔离级别,如果我们需要理解或者编写一套事务框架隔离级别将需要足够地了解。

  

原文地址:https://www.cnblogs.com/lay2017/p/12081604.html

时间: 2024-11-04 02:45:43

一、事务的基本概念的相关文章

事务的基本概念(等待修正)

摘自:http://blog.csdn.net/kid_u_forfun/article/details/7959492 该文章提供了事务的基本概念,并且通过sqlite3.exe的控制台程序,提供了简单的操作例子,而我们接下来需要讨论并不是一个简单的事务概念,而是基于源码实现的基本逻辑分析.对于银行业务来说,事务是非常重要的,而mongodb数据库并没有提供事务的支持,通过研究学习SQLite数据库在应用层提供一个事务的接口.

mysql 锁与事务的一些概念

mysql InnoDB引擎 共享锁(S) select ... lock in share mode, 加了共享锁的数据, 其它地方只能加共享锁, 不能加排他锁. 排他锁(X) select ...for update, update,delete,insert 都会自动给涉及到的数据加上排他锁, 加了排他锁的数据, 其它地方不能再加任何锁. 事务四个隔离级别1.未提交读: 可以读未提交数据.2.提交读: 只能读已提交的数据.3.可重复读: 前后两次读取数据一致, 两种情况,一种, 开启事务,

事务相关性的概念

1 什么是事务: 2 事务的特性 3 如果不考虑隔离性,引发一些读的问题 4 通过设置数据库的隔离级别来解决上述的问题. 5 如果想在Hibernate的框架中来设置隔离级别,需要在hibernate.cfg.xml的配置文件中通过标签来设置 原文地址:https://www.cnblogs.com/chenyanlong/p/9757963.html

javaweb学习总结(三十八)——事务

一.事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐,对应于如下两条sql语句  update from account set money=money+100 where name='B';  update from account set money=money-100 where name='A'; 二.MySQL数据库中操作事务命令 1.编写测试SQL脚本,如下: 1 /*创建账户表*/ 2 create table acco

深入分析事务的隔离级别

本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接是互不影响的,所以,在多个事务并发操作的过程中,如果控制不好隔离级别,就有可能产生脏读.不可重复读或

【故障处理】分布式事务ORA-01591错误解决

[故障处理]分布式事务ORA-01591错误解决 1  BLOG文档结构图       2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① 分布式事务的简单概念         ② ORA-01591错误解决   Tips: ① 本文在ITpub(http://blog.itpub.net/26736162).博客园(http://www.cnblogs.com/lhrbest)和微信公众号(x

[数据库事务与锁]详解四: 数据库的锁机制

注明: 本文转载自http://www.hollischuang.com/archives/898 数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念. 并发控制 在计算机科学,特别是程序设计.操作系统.多处理机和数据库等领域,并发控制(Concurrency control)是确保及时纠正由并发操作导致的错误的一种机制. 数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存

[数据库事务与锁]详解三: 深入分析事务的隔离级别

注明: 本文转载自http://www.hollischuang.com/archives/943 本文详细介绍四种事务隔离级别,并通过举例的方式说明不同的级别能解决什么样的读现象.并且介绍了在关系型数据库中不同的隔离级别的实现原理. 在DBMS中,事务保证了一个操作序列可以全部都执行或者全部都不执行(原子性),从一个状态转变到另外一个状态(一致性).由于事务满足久性.所以一旦事务被提交之后,数据就能够被持久化下来,又因为事务是满足隔离性的,所以,当多个事务同时处理同一个数据的时候,多个事务直接

2015第24周一Spring事务

1. Spring事务管理简介 (1)Spring为多种不同类型的事务管理机制提供统一编程模型,这些事务管理模型包括JTA.JDBC.Hibernate.JPA和JDO. (2)Spring支持声明式事务管理(使用XML文档配置(或者Annotation)结合AOP实现的事务管理). (3)为代码嵌入式(programmatic)的事务管理提供API接口,与复杂的JTA接口相比要简单的多. (4)能够与Spring的数据抽象访问完美结合. 2. Spring事务管理的优点 一般认为,JavaEE