什么是事务?事务的四大特性、事务的隔离级别

一、事务介绍

  事务管理是企业级应用程序开发中必不可少的技术, 用来确保数据的完整性和一致性

  事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用。

  数据库向用户提供保存当前程序状态的方法,叫事务提交(commit);当事务执行过程中,使数据库忽略当前的状态并回到前面保存的状态的方法叫事务回滚(rollback)

二、事务的四大特性(ACID)

  • 原子性(atomicity):事务是一个原子操作 , 由一系列动作组成,事务的原子性确保动作要么全部完成要么完全不起作用。

  • 一致性(consistency): 一旦所有事务动作完成,事务就被提交.,数据和资源就处于一种满足业务规则的一致性状态中。比如说,A和B的账户里面共有10000元,不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还是10000。

  • 隔离性(isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如,A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

  • 持久性(durability):一旦事务完成, 无论发生什么系统错误, 它的结果都不应该受到影响. 通常情况下,事务的结果被写到持久化存储器中。

事务四大特性之间的关系:

  • 原子性是基础
  • 隔离性是手段
  • 持久性是目的
  • 一致性是最终结果(老大)

三、事务的隔离级别

1、事务并发产生的问题

(1)脏读

  事务A读取了事务B未提交的数据。例如:用户A向用户B转账1000元,A通知B查看账户,B发现前确实已到账,而之后无论第二条SQL是否执行,只要该事务部提交,则所有操作都将回滚,当B再次查看账户时就会发现前其实并没有到账。

(2)不可重复读

  事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。例如:事务A在读取某一数据时,而事务B立马修改了这个数据并且提交事务给数据库,事务A再次读取该数据就得到了不同的结果,发生了不可重复读。

脏读与不可重复读的区别:

  • 脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

(3)幻读(虚读)

  这是当事务不是独立执行时发生的一种现象。例如:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

不可重复读与幻读的区别与联系:

不同点:

  • 不可重复读侧重于修改,幻读侧重于新增或删除。
  • 不可重复读查询的都是同一数据项,而幻读针对的是一批数据整体。
  • 解决方式不同:解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。

相同点:

  • 幻读和不可重复读都读取的是另一条已经提交的事务。

2、事务的隔离级别

事务的隔离级别 脏读 不可重复读 幻读
读未提交(Read-Uncommitted)
读已提交(Read-Committed)
可重复读(Repeatable-Read)
串行化(Serializable)

注意:

  • 四种隔离级别,Seralizable级别最高,Read uncommitted级别最低。级别越高,执行效率就越低。
  • 隔离级别的设置只对当前链接有效,对JDBC操作数据库来说,一个Connection对象相当于一个链接,只对该Connection对象设置的隔离级别有效,与其它链接connection对象无关。
  • Mysql的默认隔离级别是:可重复读:Repeatable read。oracle数据库中,只支持seralizable(串行化)级别和Read committed(),默认的是Read committed级别。
  • 设置数据库的隔离级别一定要是在开启事务之前。
  • 事务的隔离级别并不是越高越好。事务的隔离级别越高,越消耗数据库性能。

3、四种隔离级别发生场景

1) Read uncommitted 读未提交

  公司发工资了,领导把5000元打到小明的账户上,但是该事务并未提交,而小明正好去查看账户,发现工资已经到账,是5000元整,非常高兴。可是不幸的是,领导发现发给小明的工资金额不对,应该是4000元,于是迅速回滚了事务,修改金额后,将事务提交,最后小明实际的工资只有2000元,小明空欢喜一场。

2)Read committed 读已提交
  小明拿着工资卡去消费,系统读取到卡里有4000元,而此时她的老婆正好在网上转账,把小明工资卡的4000元转到了另一账户,并在小明之前提交了事务,当singo扣款时,系统检查到小明的工资卡已经没有钱,扣款失败。小明十分纳闷,明明卡里有钱,为何就没了…
  它是SQL Server与Oracle默认的隔离级别。

3)Repeatable read 可重复读
  当小明拿着工资卡去消费时,一旦系统开始读取工资卡信息(即事务开始),小明的老婆就不能对该记录进行修改,也就是小明的老婆不能在此时转账。
  它是MySQL的默认隔离级级别。

4)幻读
   小明某一天去消费,他老婆经常会检查他的消费记录。有一天,她查询到小明当月信用卡的总消费金额(select sum(amount) from transaction where month = 本月)为500元,而小明此时正好在外面和朋友吃饭后在收银台买单,消费了800元,即新增了一条800元的消费记录(insert transaction … ),并提交了事务。随后,小明的老婆将小明当月信用卡消费的明细打印到纸上,却发现消费总额为1300元,突然多消费了800元,以为出现了幻觉,幻读就这样产生了。

你可能感兴趣的:(数据库)