数据库事务

简介

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

事务的特性:ACID

  1. A,也就是原子性(Atomicity)。原子的概念就是不可分割,你可以把它理解为组成物质的基本单位,也是我们进行数据处理操作的基本单位。
  2. C,就是一致性(Consistency)。一致性指的就是数据库在进行事务操作后,会由原来的一致状态,变成另一种一致的状态。也就是说当事务提交后,或者当事务发生回滚后,数据库的完整性约束不能被破坏。
  3. I,就是隔离性(Isolation)。它指的是每个事务都是彼此独立的,不会受到其他事务的执行影响。也就是说一个事务在提交之前,对其他事务都是不可见的。
  4. D,指的是持久性(Durability)。事务提交之后对数据的修改是持久性的,即使在系统出故障的情况下,比如系统崩溃或者存储介质发生故障,数据的修改依然是有效的。因为当事务完成,数据库的日志就会被更新,这时可以通过日志,让系统恢复到最后一次成功的更新状态。

数据库隔离级别

事务并发可能存在的异常有哪些?

1、脏读: 读到了其他事务还没有提交的数据。

例子:A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。

2、丢失修改(Lost to modify)指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

3、不可重复读:前后多次读取,数据内容不一致

例子:事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。

4:幻读:前后多次读取,数据总量不一致

事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。

不可重复度和幻读区别: 不可重复读针对的是修改操作,幻读针对的于新增或者删除操作。

事务的四种隔离级别

1、读未提交(READ-UNCOMMITTED):也就是允许读到未提交的内容,这种情况下查询是不会使用锁的,可能会产生脏读、不可重复读、幻读等情况。

2、读已提交(READ-COMMITTED):读已提交就是只能读到已经提交的内容,可以避免脏读的产生,属于RDBMS中常见的默认隔离级别(比如说Oracle和SQL Server),但如果想要避免不可重复读或者幻读,就需要我们在SQL查询的时候编写带加锁的SQL语句。

3、可重复读(REPEATABLE-READ),保证一个事务在相同查询条件下两次查询得到的数据结果是一致的,可以避免不可重复读和脏读,但无法避免幻读。MySQL默认的隔离级别就是可重复读。

4、可串行化(SERIALIZABLE),将事务进行串行化,也就是在一个队列中按照顺序执行,可串行化是最高级别的隔离等级,可以解决事务读取中所有可能出现的异常情况,但是它牺牲了系统的并发性。

事物隔离的实现

在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。

假设一个值从 1 被按顺序改成了 2、3、4,在回滚日志里面就会有类似下面的记录。

事务隔离的实现:每条记录在更新的时候都会同时记录一条回滚操作。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)

事务启动方式:一、显式启动事务语句,begin或者start transaction,提交commit,回滚rollback;二、set autocommit=0,该命令会把这个线程的自动提交关掉。这样只要执行一个select语句,事务就启动,并不会自动提交,直到主动执行commit或rollback或断开连接。

常见数据库事物面试题

  • 介绍一下数据库的事务
  • Mysql 有哪些隔离级别
  • Mysql 什么情况会造成脏读、可重复读、幻读?如何解决。
  • Mysql 在可重复读的隔离级别下会不会有幻读的情况,为什么?
  • Mysql 事务是如何实现的。


var gitalk = new Gitalk({
“clientID”: “clientId”,
“clientSecret”: “clientSecret”,
“repo”: “GitHub repo”,
“owner”: “GitHub repo owner”,
“admin”: [“GitHub repo admin”],
“id”: location.pathname,
“distractionFreeMode”: false
});
gitalk.render(“gitalk-container”);


  转载请注明: Hi 高虎 数据库事务

  目录