什么是事务

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

事务解释:指要做的或所做的事情

事务本质:一系列操作

事务特性:事务是恢复和并发控制的基本单位。

例如 网上购物,其交易过程至少包括以下几个步骤的操作:

- 更改客户所购商品的库存信息;

- 保存客户付款信息;

- 生成订单并且保存到数据库中;

- 更改用户相关信息,例如购物数量等。

在正常情况下,这些操作都将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新。但是,如果在执行的途中遇到突然断电或者其他意外情况,导致这一系列过程中任何一个环节出了差错,例如在更细商品库存信息时发生异常、顾客银行账户余额不足等,都将导致整个交易过程失败。而一旦失败,数据库中所有信息都必须保持交易不影响数据库的状态,即原有的库存信息没有被更新、用户也没有付款、订单也没有生成。否则,数据库的信息将会不一致,或者出现更为严重的不可预测的后果。数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。

事务的属性

事务必须满足四个属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),即ACID四种属性。

(1)原子性

一个事务是一个不可分割的整体,为了保证事务的总体目标,事务必须具有原子性,即当数据修改时,要么全都执行,要么全都不执行。即,不允许事务部分地完成,避免了只执行这些操作的一部分而带来的错误。

(2)一致性

一个事务在执行之前和执行之后,数据库数据必须保持一致性。数据库的一致性状态应该满足模式锁指定的约束条件,那么在完整执行该事务后,数据库仍然处于一致性状态。

例如:银行转账,转账前后两个账户金额之和应保持不变。

(3)隔离性

由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据库时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

例如:对任何一对事务T1和T2,对T1而言,T2要么在T1开始之前已经结束,要么在T1完成之后再开始执行。

(4)持久性

也被称为永久性,事务完成以后,DBMS(数据库管理系统)保证它对数据库中数据的修改是永久性的,当系统或介质发生故障时,该修改也永久保持。持久性一般通过数据库备份与恢复来保证。

注意 严格而言,数据库事务属性都是由数据库管理系统来进行保证的,在整个应用程序的运行过程中,应用程序无须去考虑数据库的ACID实现。

一般情况下,通过执行COMMIT(提交)或ROLLBACK(回滚)语句来终止事务。当执行COMMIT语句时,自从事务启动以来对数据库所做的一切更改就成为永久性的,即被写入到磁盘,而当执行ROLLBACK语句时,自从事务启动以来对数据库所做的一切更改都会被撤销,并且数据库中内容返回到事务开始之前所处的状态。无论什么情况,在事务完成时,都能保证回到一致性状态。

并发控制

(1)DBS(数据库系统)一个明显的特点是多个用户共享数据库资源,尤其是多个用户可以同时存取相同数据。

串行控制:如果事务是顺序执行的,即一个事务完成之后,再开始另一事务。

并行控制:如果DBMS可以同时接受多个事务,并且这些事务在时间上可以重叠执行。

(2)并发控制概述

事务是并发控制的基本单位,保证事务ACID的特性是事务处理的重要任务,而并发操作有可能会破坏其ACID特性。

DBMS并发控制机制的责任:对并发操作进行正确调度,保证事务的隔离更一般,确保数据库的一致性。

由于并发操作带来的数据不一致性

如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。由于并发操作带来的数据不一致性包括:丢失数据更新、读“脏”数据(脏读)、不可重复读。

(1)更新丢失

两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发并没有被隔离开来。

(2)脏读

一个事务读取到了另一事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。

(3)不可重复读

不可重复读(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。包括以下情况:

虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读取该数据时得到与前一次不同的值。

幻读:事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据。这是因为在两次查询过程中有另外一个事务插入数据造成的。

事务隔离级别

为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。

读未提交(Read Uncommitted)

只处理更新丢失。

如果一个事务已经开始写数据,则不允许其他事务同时进行写操作,但允许其他事务读此行数据。

可通过“排他写锁”实现。

读已提交(Read Committed)

处理更新丢失、脏读。

读取数据的事务允许其他事务继续访问改行数据,但是未提交的写事务将会禁止其他事务访问改行。

可通过“瞬间共享读锁”和“排他写锁”实现。

可重复读取(Repeatable Read)

处理更新丢失、脏读和不可重复读取。

读取数据的事务将会禁止写事务,但允许读事务,写事务则禁止任何其他事务。

可通过“共享读锁”和“排他写锁”实现。

序列化(Serializable)

提供严格的事务隔离。

要求失去序列化执行,事务只能一个接一个地执行,不能并发执行。

仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别越高,越能保证数据的完整性和统一性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

MySQl

MySql默认的隔离级别为Repeatable Read,因此只会出现幻读的情况。

幻读

事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据如同鬼影一般。

例子:

在事务1中,查询User表id为1的是用户否存在,如果不存在则插入一条id为1的数据。

select * from User where id = 1;

在事务1查询结束后,事务2往User表中插入了一条id为1的数据。

insert intoUser(id,name) values (1, 'Joonwhee');

此时,由于事务1查询到id为1的用户不存在,因此插入1条id为1的数据。

insert into ` User`(`id`, `name`) values (1, 'Chillax');

但是由于事务2已经插入了1条id为1的数据,因此此时会报主键冲突,对于事务1 的业务来说是执行失败的,这里事务1 就是发生了幻读,因为事务1读取的数据状态并不能支持他的下一步的业务,见鬼了一样。这里要灵活的理解读取的意思,第一次select是读取,第二次的insert其实也属于隐式的读取,只不过是在mysql的机制中读取的,插入数据也是要先读取一下有没有主键冲突才能决定是否执行插入。

Oracle

Oracle默认的隔离级别为Read Committed,因此可能出现不可重复度和幻读。

不可重复读

同样的条件,你读取过的数据,再次读取出来发现值不一样了。

例子:

在事务1中,JoonWhee读取了自己的工资为1000,但是此时事务1的操作还并没有完成 ,后面还有1次相同的读取操作。

con1 = getConnection();

select salary from employee where employeeName="JoonWhee";

在事务2中,这时财务人员修改了JoonWhee的工资为2000,并提交了事务。

con2 = getConnection(); update employee set salary = 2000 where employeeName = "JoonWhee"; con2.commit();

在事务1中,JoonWhee再次读取自己的工资时,工资变为了2000 。

select salary from employee where employeeName ="JoonWhee";

在一个事务中前后两次读取的结果并不一致,导致了不可重复读。

幻读

同样的条件,第1次和第2次读出来的记录数不一样。

例子:

目前工资为1000的员工有10人。

事务1,读取所有工资为1000的员工,共读取10条记录 。

con1 = getConnection();

Select * from employee where salary =1000;

这时另一个事务向employee表插入了一条员工记录,工资也为1000

con2 = getConnection(); Insert into employee(employeeName,salary) values("Lili",1000); con2.commit();

事务1再次读取所有工资为1000的员工,共读取到了11条记录,这就产生了幻读。

select * from employee where salary =1000;

扩展阅读:

mysql隔离级别 简书_数据库事务和四种隔离级别相关推荐

  1. 数据库事务的四种隔离级别

    文章目录 1. 引言 2. 事务隔离级别 2.1 事务四种隔离级别 2.2 查看隔离级别 3. 脏读/幻读/不可重复读 3.1 脏读 3.2 不可重复读 3.3 幻读 4. 总结: 1. 引言 &qu ...

  2. 事务的四种隔离级别(一)Read uncommitted

    背景知识 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 之所以提出事务隔离级别,是因为同一个应用程序中的多个事务或不同应用程序中的多个事务在同一个数据集上并发执行时, 可能会 ...

  3. 阐述一下Mysql事务的四个特性_数据库事务的四个基本性质?

    本文转载:http://www.sqlstudy.com/sql_article.php?id=2008080302 数据库事务概念 什么是数据库事务? 事务(transaction)是由一系列操作序 ...

  4. 数据库事务的四个隔离级别

    [3]事务的四个隔离级别.   事务隔离级别                     脏读       不可重复读        幻读         READ_UNCOMMITTED       允 ...

  5. MySQL事务的四种隔离界别以及会造成的问题和解决办法

    MySQL事务的特性:原子性.隔离性.持久性.一致性 MySQL四种隔离界别:读未提交.读已提交.可重复度.串行化 一.读未提交(read uncommitted): 读未提交:那个问题都不能解决.容 ...

  6. polardb mysql 事务隔离级别_事务的四种隔离级别

    数据库事务的隔离级别有4种,由低到高分别为Read uncommitted .Read committed .Repeatable read .Serializable .而且,在事务的并发操作中可能 ...

  7. 数据库事务的四个隔离级别浅析

    数据库事务的隔离级别有4个,由低到高依次为Read uncommitted (读未提交).Read committed(读提交).Repeatable read(可重复读) .Serializable ...

  8. MySQL事务的四种隔离级别,mysql中的不可重复读和幻读的区别,Repeatable read可重复读隔离级别下怎么不存在幻读问题?

    1. 事务的隔离级别 1.1 read uncommited:读未提交.一个事务读到了另一个事务未提交的脏数据,称之为脏读. 1.2 read commited:读已提交.解决了脏读问题,但当前事务两 ...

  9. oracle事务的四种隔离级别,事务的四种隔离级别

    数据库事务的四大特征 原子性 指事物包含的所有操作要么全部成功,要么全部回滚. 一致性 指事物必须是数据库从一个一致性状态到另一个一致性状态.也就是说一个事物执行之前和执行之后都必须处于一致性状态. ...

最新文章

  1. 2019年中国智能制造发展现状及趋势分析报告
  2. linux socket 套接字状态 EAGAIN EWOULDBLOCK EINTR 与非阻塞 简介
  3. git clone 几种可选参数的使用与区别
  4. salt-master
  5. python自动控制库_python PyAUtoGUI库实现自动化控制鼠标键盘
  6. java求几何周长面积_JAVA:编写求解几何图形(如三角形,矩型,圆,多边型)的周长、面积的应用程序...
  7. 人工智能ai应用高管指南_理解人工智能指南
  8. FireMonkey 跨平台框架下的图片缩放和 JPEG 编码
  9. php用for循环输出九九乘法表,php循环之打印九九乘法表
  10. 小米8鸿蒙系统,小米手机刷鸿蒙系统
  11. 【转】android builder.setPositiveButton处 报错
  12. Python类中的方法要加self的理由
  13. c++ sort 转载
  14. 第三方支付-核心交易之商户结算设计
  15. 今晚7:30 | CVPR专场四!UIUC、港中文、港科大
  16. 【BUUCTF刷题记录】[极客大挑战 2019] Http
  17. 用html实现满屋花的网页
  18. android车载娱乐系统场景,复合式娱乐综合体,共享设备集成场景化空间-迷你ktv官网...
  19. arctic数据库使用教程(1)---为啥要用arctic以及arctic的简单应用
  20. HTML链接跳转与vue链接跳转

热门文章

  1. web 静态页面和动态页面的区别
  2. python sklearn.decomposition.PCA 主成分分析, 原理详解
  3. Future和CompletableFuture的区别和对比,以及Future主要的四个缺点——不能回调会阻塞、批量任务处理彼此依赖会阻塞、不能多个任务级联执行、得不到最先完成的任务
  4. addcslashes php 有什么用处,PHP addcslashes函数有什么用
  5. 无忧考吧2017二级java_二级Java模拟软件|无忧考吧二级Java语言程序设计模拟软件下载 v2017.03官方版 - 121下载站...
  6. u盘读写测试_关于闪迪u盘cz880速度测试
  7. iOS线程锁中你还不知道的内容
  8. tomcat点击startup.bat闪退解决办法
  9. java i 什么时候变_Java中i++与++i的区别(效率分析)
  10. 画一个圆角多边形_CAD零基础教程,矩形和多边形的画法