专栏首页大闲人柴毛毛数据库事务详解

数据库事务详解

什么是『事务』?

事务就是一组具有原子性的操作,这一组操作要么全都正确执行,要么全都不执行。 事务能保证数据库从一种一致性状态转换为另一种一致性状态。

事务的四大特性ACID

1. 原子性

原子性指的是事务是一个不可分割的操作,要么全都正确执行,要么全都不执行。

2. 一致性

事务开始前和事务结束后,数据库的完整性约束没有被破坏。

3. 隔离性

事务的执行是相互独立的,它们不会相互干扰,一个事务不会看到另一个正在运行过程中的事务的数据。

4. 持久性

事务结束后,事务的结果必须是永久保存的。即使数据库发生崩溃,在数据库恢复后事务提交的结果仍然不会丢失。 PS:事务只能保证数据库的高可靠性,即数据库本身发生问题后,事务提交后的数据仍然能恢复;而如果不是数据库本身的故障,如硬盘损坏了,那么事务提交的数据可能就丢失了。这属于『高可用性』的范畴。因此,事务只能保证数据库的『高可靠性』,而『高可用性』需要整个系统共同配合实现。

事务的分类

1. 扁平事务

  • 它是实际生产环境中最常用、最简单的事务类型。
  • 事务从BEGIN WORK开始,从COMMIT WORK或ROLLBACK WORK结束。
  • 缺点:发生错误时回滚到事务的起始位置,无法回滚部分操作。而回滚所有的操作开销太大。

2. 带有保存点的扁平事务

这种事务能设置多个保存点,当发生错误时可以回滚到事务中指定的保存点,而不需要将整个事务回滚。

3. 链事务

4. 嵌套事务

5. 分布式事务

数据库并发访问会出现的问题

1. 更新丢失

当有两个并发执行的事务,更新同一行数据,那么有可能一个事务会把另一个事务的更新覆盖掉。 当数据库没有加任何锁操作的情况下会发生。

2. 脏读

一个事务读到另一个尚未提交的事务中的数据。 该数据可能会被回滚从而失效。 如果第一个事务拿着失效的数据去处理那就发生错误了。

3. 不可重复读

不可重复度的含义:一个事务对同一行数据读了两次,却得到了不同的结果。它具体分为如下两种情况: 1. 虚读:在事务1两次读取同一记录的过程中,事务2对该记录进行了修改,从而事务1第二次读到了不一样的记录。 2. 幻读:事务1在两次查询的过程中,事务2对该表进行了插入、删除操作,从而事务1第二次查询的结果发生了变化。

与『脏读』的区别? 脏读读到的是尚未提交的数据,而不可重复读读到的是已经提交的数据,只不过在两次读的过程中数据被另一个事务改过了。

事务的隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。

1. Read uncommitted 读未提交

在该级别下,一个事务对一行数据修改的过程中,不允许另一个事务对该行数据进行修改,但允许另一个事务对该行数据读。 因此本级别下,不会出现更新丢失,但会出现脏读、不可重复读。

2. Read committed 读提交

在该级别下,未提交的写事务不允许其他事务访问该行,因此不会出现脏读;但是读取数据的事务允许其他事务的访问该行数据,因此会出现不可重复读的情况。

3. Repeatable read 重复读

在该级别下,读事务禁止写事务,但允许读事务,因此不会出现同一事务两次读到不同的数据的情况(不可重复读),且写事务禁止其他一切事务。

4. Serializable 序列化

该级别要求所有事务都必须串行执行,因此能避免一切因并发引起的问题,但效率很低。

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

使用事务的注意事项

1. 不要在循环中提交事务

2. 不要使用自动提交

3. 不要使用自动回滚

4. 不要使用长事务

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常用的分布式事务解决方案

    众所周知,数据库能实现本地事务,也就是在同一个数据库中,你可以允许一组操作要么全都正确执行,要么全都不执行。这里特别强调了本地事务,也就是目前的数据库只能支持...

    大闲人柴毛毛
  • Redis源码分析(三)——Redis数据结构-字典

    1. 数据结构 ? 1.1 哈希表 typedef struct dictht{ dictEntry **table; unsigned long s...

    大闲人柴毛毛
  • 深入理解JVM(八)——类加载的时机

    类的生命周期 一个类从加载进内存到卸载出内存为止,一共经历7个阶段: 加载——>验证——>准备——>解析——>初始化——>使用——>卸载 其中,类加载包括...

    大闲人柴毛毛
  • spring的4种事务特性,5种隔离级别,7种传播行为

    spring事务: 什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.

    奋斗蒙
  • Spring事物的传播行为案例分析

    1、spring给出经常面试的考点Spring事务的4个特性含义---这个很容易理解

    宜信技术学院
  • Try-Catch包裹的代码异常后,竟然导致了产线事务回滚!

    产线部分数据丢失了,因为一个蹊跷的事务回滚。而造成事务回滚的,竟然是一段被try-cath包裹后的代码,一段已经在产线稳定运行了200天的代码,稳定到我们已经把...

    用户1516716
  • Spring源码剖析8:Spring事务概述

    事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务。

    Java技术江湖
  • 重新学习MySQL数据库6:浅谈MySQL的中事务与锁

    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看

    Java技术江湖
  • 事务分类---innodb存储引擎笔记+闲扯

    事务想必大家都比较熟悉,我们可能张口就来ACID,但是事务的分类,之前我没怎么关心过,今天看姜大神的书MySQL技术内幕---innodb存储引擎看到了这...

    AsiaYe
  • MySQL基础之事务编程学习笔记

    在学习《MySQL技术内幕:SQL编程》一书,并做了笔记。本博客内容是自己学了《MySQL技术内幕:SQL编程》事务编程一章之后,根据自己的理解做的笔记,内容和...

    用户1208223

扫码关注云+社区

领取腾讯云代金券