当前位置: 首页 > news >正文

个人网站建站系统黄冈网站推广软件

个人网站建站系统,黄冈网站推广软件,查找网站,跨境c2c电商平台有哪些文章目录 数据库事务事务特性(ACID)原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability) 隔离级别Read Uncommitted(读未提交)Read Committed(读已提交)Repeatable Read(可重复读)Serializable(可串行化) Spring事务机制实现方式提交方式事务隔离级别事务…

文章目录

  • 数据库事务
    • 事务特性(ACID)
      • 原子性(Atomicity)
      • 一致性(Consistency)
      • 隔离性(Isolation)
      • 持久性(Durability)
    • 隔离级别
      • Read Uncommitted(读未提交)
      • Read Committed(读已提交)
      • Repeatable Read(可重复读)
      • Serializable(可串行化)
    • Spring事务机制
      • 实现方式
      • 提交方式
      • 事务隔离级别
      • 事务传播行为
      • 事务回滚规则
      • 事务常用配置
      • 失效场景

数据库事务

什么叫事务?

事务是一系列对系统中数据进行访问与更新的操作组成的一个程序逻辑单元。即不可分割的许多基础数据库操作。

事务特性(ACID)

原子性(Atomicity)

原子性是指一个事务(事务是最小的执行单位)是一个不可分割的工作单元,其中的操作要么都做,要么都不做。如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。

实现原理

① 回滚日志(undo log)

InnoDB实现回滚靠的是undo log。当事务对数据库进行修改时,InnoDB会生成对应的undo log。如果事务执行失败或调用了rollback,导致事务需要回滚,便可利用undo log中的信息将数据回滚到修改前。

  • 对于每个insert,回滚时会执行delete
  • 对于每个 delete,回滚时会执行insert
  • 对于每个 update,回滚时会执行一个相反的 update,把数据改回去

一致性(Consistency)

一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。

数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。

实现原理

一致性是事务追求的最终目标。前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。实现一致性的措施包括:

① 保证原子性、持久性和隔离性。如果这些特性无法保证,事务的一致性也无法保证

② 数据库本身提供保障。如不允许向整型列插入字符串值、字符串长度不能超过列的限制等

③ 应用层面进行保障。如转账操作只扣除转账者余额,而未增加接收者余额

隔离性(Isolation)

**隔离性是指事务内部的操作与其它事务是隔离的,并发执行的各个事务之间不能互相干扰。**严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。

实现原理

隔离性追求的是并发情形下事务之间互不干扰。主要分为两个方面:

① 加锁机制保证隔离性:(一个事务)写操作对(另一个事务)写操作的影响

事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其它事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

② MVCC(多版本并发控制)保证隔离性:(一个事务)写操作对(另一个事务)读操作的影响

MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议。最大优点是读不加锁,因此读写不冲突,并发性能好。InnoDB的MVCC实现了多个版本的数据可共存,主要基于以下技术及数据结构:

  • 隐藏列:在Innodb引擎中每行数据都会有两个隐藏列(实际是三个列)
    • 隐藏idid,如果建表时没有显式指定,则会生成这个隐藏id作为主键,实际和mvcc没有关系)
    • 创建版本号data_trx_id,事务id):用来标识最近对本行记录做修改的事务 id
    • 回滚指针data_roll_pointer,指向undo log的指针)
  • 基于undo log版本链:每条undo log也会指向更早版本的undo log,从而形成一条版本链
  • ReadView:**通过隐藏列和版本链可以将数据恢复到指定版本,但具体要恢复到哪个版本,则需要根据ReadView来确定。**当进行查询操作时,事务会生成一个ReadView(是一个事务快照),准确来说是当前时间点系统内活跃的事务列表,也就是说系统内所有未提交的事务,都会记录在这个Readview内,事务就根据它来判断哪些数据是可见的,哪些是不可见的。在每一条 SQL 开始的时候被创建,有几个重要属性:
    • trx_ids: 当前系统活跃(未提交)事务版本号集合
    • low_limit_id: 创建当前 read view 时“当前系统最大事务版本号+1”
    • up_limit_id: 创建当前read view 时“系统正处于活跃事务最小版本号”
    • creator_trx_id: 创建当前read view的事务版本号

MVCC查询流程

现在开始查询,一个 select 过来了,找到了一行数据。

  • data_trx_id < up_limit_id:说明数据在当前事务之前就存在了,显示
  • data_trx_id >= low_limit_id:说明该数据是在当前read view 创建后才产生的,数据不显示。不显示怎么办,根据 data_roll_pointer 从 undo log 中找到历史版本,找不到就空
  • up_limit_id < data_trx_id < low_limit_id:就要看隔离级别了

MVCC应用场景

在Mysql的InnoDB引擎中,只有已提交读可重复读这两种隔离级别的事务采用了MVCC机制:

  • 已提交读(READ COMMITTD):事务中的每次读操作都会生成一个新的ReadView,也就是说如果这期间某个事务提交了,那么它就会从ReadView中移除。这样确保事务每次读操作都能读到相对比较新的数据
  • 可重复读(REPEATABLE READ):事务只有在第一次进行读操作时才会生成一个ReadView,后续的读操作都会重复使用这个ReadView。也就是说如果在此期间有其他事务提交了,那么对于可重复读来说也是不可见的,因为对它来说,事务活跃状态在第一次进行读操作时就已经确定下来,后面不会修改了

持久性(Durability)

持久性是指事务一旦提交,它对数据库的改变就应该是永久性的,即使数据库发生故障也不受影响。

实现原理

① redo log

当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘(刷脏页)。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。

为什么redo log写入磁盘比直接将Buffer Pool中修改数据写入磁盘(刷脏)快?

  • 刷脏是随机I/O,因为每次修改的数据位置随机,但写redo log是追加操作,属于顺序I/O
  • 刷脏是以数据页(Page)为单位的,MySQL默认页大小是16KB,一个Page上一个小修改都要整页写入;而redo log中只包含真正需要写入的部分,无效I/O大大减少

隔离级别

事务并发问题

在事务的并发操作中,不做隔离操作则可能会出现 脏读、不可重复读、幻读 问题:

  • 脏读指一个事务读取到了另一个未提交事务修改过的数据

    事务A中读到了事务B中未提交的更新数据内容,然后B回滚操作,那么A读取到的数据是脏数据。

  • 不可重复读同一个事务内,前后多次读取,读取到的数据内容不一致

    事务A读到事务B已经提交后的数据,即事务A多次读取同一数据时,返回结果不一致。

  • 幻读指一个事务先根据某些搜索条件查询出一些记录,在该事务未提交时,另一个事务写入了一些符合那些搜索条件的记录(如insert、delete、update),再次查询出的结果则出现不一致

    事物A执行select后,事物B增或删了一条数据,事务A再执行同一条SQL后发现多或少了一条数据。

  • 第一类丢失更新: A事务撤销事务时,覆盖了B事务提交的事务(现代关系型数据库中已经不会发生)

  • 第二类丢失更新: A事务提交事务时,覆盖了B事务提交的事务(是不可重复读的特殊情况)

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。查看 mysql 事务隔离级别:show variables like 'tx_iso%';

InnoDB存储引擎下的四种隔离级别发生问题的可能性如下:

隔离级别第一类丢失更新第二类丢失更新脏读不可重复读幻读
Read Uncommitted(读未提交)不可能可能可能可能可能
Read Committed(读已提交)不可能可能不可能可能可能
Repeatable Read(可重复读)不可能不可能不可能不可能可能
Serializable(串行化)不可能不可能不可能不可能不可能

Read Uncommitted(读未提交)

只限制了两个数据不能同时修改,但即使事务未提交也会读取到其它事务未提交的内容(可能会被回滚)。会有脏读、重复读、幻读的问题,读取未提交的数据,也被称之为脏读(Dirty Read)

特点:最低级别,任何情况都无法保证

数据库锁情况

  • 读取数据:未加锁,每次都读到最新数据,性能最好
  • 写入数据:只对数据增加行级共享锁,写完释放

Read Committed(读已提交)

当前事务只能读取到其它事务已提交的数据。因同一事务的其它实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同结果,这就是所谓的不可重复读(Nonrepeatable Read)。该隔离级别解决了脏读问题,但还是会存在重复读、幻读问题。

特点:避免脏读

脏读解决方案:基于乐观锁理论的MVCC(多版本并发控)实现

数据库锁情况

  • 读取数据:加行级共享锁(读到时才加锁),读完后立即释放
  • 写入数据:在更新时的瞬间对其加行级排它锁,直到事务结束才释放

Repeatable Read(可重复读)

限制了读取数据时不可以进行修改,所以解决了不能重复读的问题。但是读取范围数据的时候,是可以插入或删除数据,所以还会存在**幻读(Phantom Read)**问题。

幻读 是户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当该用户再读取该范围的数据行时,会发现有新的“幻影” 行。

特点:避免脏读、不可重复读。MySQL默认事务隔离级别

不可重复读解决方案:基于乐观锁理论的MVCC(多版本并发控)实现

数据库锁情况

  • 读取数据:开始读取的瞬间对其增加行级共享锁,直到事务结束才释放
  • 写入数据:开始更新的瞬间对其增加行级排他锁,直到事务结束才释放

Serializable(可串行化)

所有事务都是进行串行化顺序执行的。可以避免脏读不可重复读幻读所有并发问题。但该事务隔离级别下,事务执行很耗性能。

特点:避免脏读、不可重复读、幻读

数据库锁情况

  • 读取数据:先对其加表级共享锁 ,直到事务结束才释放
  • 写入数据:先对其加表级排他锁 ,直到事务结束才释放

Spring事务机制

实现方式

在Spring中事务有两种实现方式:

  • 编程式事务管理: 编程式事务管理使用TransactionTemplate或直接使用底层的PlatformTransactionManager
  • 声明式事务管理: 建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单

提交方式

默认情况下,数据库处于自动提交模式。每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成功则隐式的提交事务,如果执行失败则隐式的回滚事务。
对于正常的事务管理,是一组相关的操作处于一个事务之中,因此必须关闭数据库的自动提交模式。不过,这个我们不用担心,Spring会将底层连接的自动提交特性设置为false。也就是在使用Spring进行事物管理的时候,Spring会将是否自动提交设置为false,等价于JDBC中的 connection.setAutoCommit(false);,在执行完之后在进行提交,connection.commit();

事务隔离级别

隔离级别是指若干个并发的事务之间的隔离程度。

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void addGoods(){......
}

枚举类Isolation中定义了五种隔离级别:

  • DEFAULT:默认值。表示使用底层数据库的默认隔离级别。对大部分数据库,通常这值就是READ_COMMITTED
  • READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别
  • READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值
  • REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读
  • SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别

事务传播行为

事务的传播性一般用在事务嵌套的场景,如一个事务方法里面调用了另外一个事务方法,那两个方法是各自作为独立的方法提交还是内层事务合并到外层事务一起提交,这就需要事务传播机制配置来确定怎么样执行。

@Transactional(propagation=Propagation.REQUIRED)
public void addGoods(){......
}

枚举类Propagation中定义了七种事务传播机制如下:

  • REQUIRED(required,要求,Spring默认):当前存在事务,则加入该事务;当前没有事务,则创建一个新的事务
  • REQUIRES_NEW(requires_new,要求新的):创建一个新事务,如果存在当前事务,则挂起该事务
  • SUPPORTS(supports,支持):如果当前存在事务,则加入当前事务;如果当前没有事务,就以非事务方法执行
  • NOT_SUPPORTED(not_supported,不支持):始终以非事务方式执行,如果当前存在事务,则挂起当前事务
  • NEVER(never,都不):不使用事务,如果当前事务存在,则抛出异常
  • MANDATORY(mandatory,强制):如果当前存在事务,则加入当前事务;如果当前事务不存在,则抛出异常
  • NESTED(nested,嵌套)如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)

事务回滚规则

指示Spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。Spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。
默认配置下,Spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。
可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。

事务常用配置

  • readOnly

    该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。例如:@Transactional(readOnly=true)

  • rollbackFor

    该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。例如:指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

  • rollbackForClassName

    该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。例如:指定单一异常类名称@Transactional(rollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})

  • noRollbackFor

    该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。例如:指定单一异常类:@Transactional(noRollbackFor=RuntimeException.class)指定多个异常类:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

  • noRollbackForClassName

    该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。例如:指定单一异常类名称:@Transactional(noRollbackForClassName=”RuntimeException”)指定多个异常类名称:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})

  • propagation

    该属性用于设置事务的传播行为。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

  • isolation

    该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可,基本不需要进行设置

  • timeout

    该属性用于设置事务的超时秒数,默认值为-1表示永不超时

失效场景

  • @Transactional 应用在非 public 修饰的方法上
  • 数据库引擎要不支持事务
  • 由于propagation 设置错误,导致注解失效
  • rollbackFor 设置错误,@Transactional 注解失效
  • 方法之间的互相调用也会导致@Transactional失效
  • 异常被你的 catch“吃了”导致@Transactional失效
http://www.qdjiajiao.com/news/11926.html

相关文章:

  • 秦皇岛网站排名最近有哪些新闻
  • 云网站制作的流程北京seo实战培训班
  • 深圳哪家网站建设好中国最新新闻
  • flash 制作网站交换友链是什么意思
  • 万州论坛网站建设seo网站优化
  • 资源网站快速优化排名今日财经最新消息
  • 营销型网站的目标是yandex网站推广
  • 广州优质网站排名公司提高工作效率的重要性
  • 网站建设招标书组成网络推广员怎么做
  • 怎么做网站下载链接短网址
  • 卖酒网站排名常州网站优化
  • 网站搭建设计seo查询外链
  • wordpress 开启日志南宁网站优化公司电话
  • 做品牌网站seo线下培训班
  • 旅游公司网站开发衡阳seo
  • 网站建设文书百度网站大全首页
  • wordpress 千万数据郑州seo网站有优化
  • 上海市建上海市建设安全协会网站今天最新消息
  • 网站建设中两个变量合并操作竞价推广的企业
  • 旅游景区网站建设百度查询最火的关键词
  • 哪家公司做网站便宜百度网址导航
  • 网站seo优化技术入门百度网站优化排名
  • 专业网站建设的网站做成app
  • 重庆手机网站推广资料营销平台建设
  • 福州专业建站公司关键词排名点击软件怎样
  • 网站设计页面如何做居中如何引流与推广
  • 电商网站建设效果seo优化中以下说法正确的是
  • 阿里巴巴网站分类板块做全屏知识搜索引擎
  • 上海这边敲墙拆旧做啥网站的比较多怎么建网站
  • 网站域名建设费进什么科目谷歌浏览器安卓下载