【MySQL系列】MySQL事务知识点

发布时间:2022-07-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【MySQL系列】MySQL事务知识点脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

事务的特性

ACID(AtomicITy、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)

  • AtomicityF1a;原子性,执行的最小单元,不可拆分。
  • Consistency:一致性,事务在执行DML操作时,要么成功,要么失败。
  • Isolation:隔离性。两个事务执行具有隔离性。
  • Durability:持久性。事务执行以后,对数据库的影响是持久的。

MySQL事务常用的命令

  • 开启事务:两个都可以

    begin;
    start transaction;
    
  • 提交事务

    commit;
    
  • 回滚事务

    rollback;
    
  • 查看当前对话的隔离级别

    select @@tx_isolation;
    
  • 查看系统当前的隔离级别

    select @@global.tx_isolation;
    
  • 设置会话级隔离级别为读未提交:

    set session transaction isolation level read uncommitted;
    
  • 设置全局级隔离级别为读未提交:

    set global transaction isolation level read uncommitted;
    
  • 设置自动提交

    set autocommit = 0/1; (0为不自动提交,1为自动提交)
    

事务的隔离级别

作用范围

  • 全局级:对所有的会话有效
  • 会话级:只对当前的会话有效

事务隔离级别

从上往下,并发性越来越差,安全性越来越高。

  • 读未提交

    Read UnCommitted。一个事务可以看到另一个事务未提交的数据。一般很少用。

    带来的问题:脏读。

  • 读已提交

    Read Commited,简称RC。大多数数据库系统默认RC。

    定义:一个事务开始时,只能"看见"已经提交的事务做的修改,也就是说:一个事务从开始到提交之前,所做的任何修改对其他事务都是不可见的。

    带来的问题:不可重复读,即两次执行相同的查询,可能会得到不同的结果。

  • 可重复读

    RePEatable Read,简称RR。

    同一个事务多次读取同样的记录的结果是一致的。

    带来的问题:幻读,即当某个事务在读取某个范围内的记录时,另一个事务又在该范围插入了新的记录,当某个事务再次读取该范围内的记录时,会产生幻行。

    InnoDB和XtraDB通过MVCC解决了幻读的问题。

  • 串行化

    Serializable。读写都会加锁,锁住整张表,很少用。

    通过强制事务串行执行,避免幻读问题。Serializable会在每一行数据上都加锁,所以可能会导致大量超时和锁争用的问题。

    事务隔离级别并发问题

【MySQL系列】MySQL事务知识点

特别说明点

  • 默认隔离层级:;mySQL—可重复读。oracle,sql server —读已提交
  • 事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以止幻读。

如何设置事务级别

使用Mysql命令对数据库进行操作。

mysql默认隔离层级

查询mysql的默认事务隔离级别的命令:REPEATABLE-READ

【MySQL系列】MySQL事务知识点

事务隔离层级

以读未提交为例,其他的内容参考最下面推荐的文章

执行的内容:在事务A开启读未提交时,事务B更新数据时,事务A就能查到数据。

【MySQL系列】MySQL事务知识点

事务B做操作:开启读未提交命令,还未提交事务,事务A就能查到数据。一旦客户端B的事务因为某种原因回滚,所有的操作都将会被撤销,那客户端A查询到的数据其实就是脏数据。

【MySQL系列】MySQL事务知识点

如何实现事务隔离

  • 事务隔离的实现:每条记录在更新的时候都会同时记录一条回滚操作。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。
  • 回滚日志什么时候删除?系统会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。
  • 什么时候不需要了?当系统里没有比这个回滚日志更早的read-view的时候。

长事务

什么是长事务?其实就是运行时间比较长的未提交的事务。

长事务的影响

  • 长事务意味着系统里面会存在很老的事务视图,在这个事务提交之前,回滚记录都要保留,这会导致大量占用存储空间。
  • 长事务还会占用锁资,可能会拖垮数据库。

如何查询出表中的长事务

select * From information_schema.innodb_trx;

这个表中记录了所有正在运行的事务信息,里面有事务的开始时间。可以从这里看出哪些事务运行的时间比较长。

如何避免长事务

  • 首先,从应用开发端来看:
    • 确认是否使用了 set autocommit=0。这个确认工作可以在测试环境中开展,把 MySQL 的 general_LOG 开起来,然后随便跑一个业务逻辑,通过 general_log 的日志来确认。一般框架如果会设置这个值,也就会提供参数来控制行为,你的目标就是把它改成 1。
    • 确认是否有不必要的只读事务。有些框架会习惯不管什么语句先用 begin/commit 框起来。有些是业务并没有这个需要,但是也把好几个 select 语句放到了事务中。这种只读事务可以去掉。
    • 业务连接数据库的时候,根据业务本身的预估,通过 SET max_execution_time 命令,来控制每个语句执行的最长时间,避免单个语句意外执行太长时间。(为什么会意外?在后续的文章中会提到这类案例)
  • 其次,从数据库端来看:
    • 监控 information_schema.Innodb_trx 表,设置长事务阈值,超过就报警 / 或者 kill;
    • Percona 的 pt-kill 这个工具不错,推荐使用;
    • 在业务功能测试阶段要求输出所有的 general_log,分析日志行为提前发现问题;
    • 如果使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 设置成 2(或更大的值)。如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便。

事务启动的方式

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

事务与SPRing结合

事务如何传播:即方法A传播到方法B。那方法A到方法B,方法A和B中分别要么有事务,要么没有事务。那在传播时有如下的行为:

事务传播行为(Transaction Propagation Behavior)

目前,Spring在TransactionDefinition类中定义了以下7种传播特性,具体特性我们接下来会分析:

  • PROPAGATION_REQUIred:如果不存在外层事务,就主动创建事务;否则使用外层事务;
  • PROPAGATION_SUPPORTS:如果不存在外层事务,就不开启事务;否则使用外层事务;
  • PROPAGATION_MANDATORY:如果不存在外层事务,就抛出异常;否则使用外层事务;
  • PROPAGATION_REQUIRES_NEW:总是主动开启事务;如果存在外层事务,就将外层事务挂起;
  • PROPAGATION_NOT_SUPPORTED:总是不开启事务;如果存在外层事务,就将外层事务挂起;
  • PROPAGATION_NEVER:总是不开启事务;如果存在外层事务,则抛出异常;
  • PROPAGATION_NESTED:如果不存在外层事务,就主动创建事务;否则创建嵌套的子事务;

死锁问题

死锁是什么

死锁是指两个或者多个事务互相争夺同一个资源导致的。两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而产生恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁。

如何避免死锁

数据库系统实现了各种死锁检测和死锁超时检测。InnoDB可以检测到死锁的循环依赖,并立即返回一个错误。InnoDB目前处理死锁的方法是,将持有最少行级排它锁的事务进行回滚(这是相对比较简单的死锁回滚算法)。

锁的行为和顺序是和存储引擎有关的。不同存储引擎在执行语句时,有些会产生死锁,有些则不会。

只有部分或者全部的事务回滚时,才能打破死锁。所以在程序设计时需要考虑如何处理死锁。

推荐文章

Mysql常用命令行大全

MySQL的四种事务隔离级别

Transaction 那点事儿

脚本宝典总结

以上是脚本宝典为你收集整理的【MySQL系列】MySQL事务知识点全部内容,希望文章能够帮你解决【MySQL系列】MySQL事务知识点所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。