简介:

使用场景:MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

概念:有一条或者多条sql语句组成,要么都成功,要么都失败

事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(**C**onsistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

  • **原子性:**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
  • **一致性:**在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
  • **隔离性:**数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,
  • 读未提交(Read uncommitted)
  • 读提交(read committed)
  • 可重复读(repeatable read)
  • 串行化(Serializable)。
  • **持久性:**事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

事务分类

隐式事务:

没有明显的开启和结束标记

比如DML语句insert、update、delete语句本身就是一条事务

显示事务:

具有明显的开启和结束标记

一般有多条sql语句组成

步骤:

  1. 取消自动提交 set autocommit=0 或者 set session autocommit=on
    开启自动提交 set autocommit=1 或者 set session autocommit=off
  2. 开启事务 start transation或begin
  3. 编写事务所需要的sql语句 sql语句
  4. 结束事务

提交:commit

回滚:rollback

事务并发的三大问题

数据库读一致性问题

  • 脏度:读取到的数据是其他事务未提交的数据(内存中的),导致前后两次读取到的数据不一致

mysql事务怎么写 mysql事务详解_数据库

  • 不可重复读:同一个事务,执行了两次同样的查询操作,但是读取到的数据不一致。重点是修改或者删除

mysql事务怎么写 mysql事务详解_索引_02

  • 幻读:同一个事务,执行了两次同样的查询操作,但是读取到的数据不一致。重点是新增

mysql事务怎么写 mysql事务详解_数据库_03

隔离级别

四种事务隔离级别

  • 读未提交(Read Uncommitted)
  • 读已提交(Red Committed)
  • 可重复读(Repeatable Read)
  • 串行化(Serializable):解决事务并发的所有问题,效率也是最低!!!

mysql事务怎么写 mysql事务详解_mysql事务怎么写_04

事务隔离级别的解决方案

  1. 在读取事务前,对其加锁,阻止其他事物对数据进行修改–Lock Based Concurrency Control(LBCC
  2. 生成一个数据请求时间点的一致性数据快照,并用这个快照来提供一定级别(语句级或事务级)的一致性读取–Multi Version Concurrency Control(MVCC

数据库锁

锁的粒度

表锁与行锁的区别:

  • 锁定粒度:表锁 > 行锁
  • 加锁效率:表锁 > 行锁
  • 冲突概率:表锁 > 行锁
  • 并发性能:表锁 < 行锁

MyISAM只支持表锁,InnoDB支持表锁和行锁

InnoDB锁类型

锁的模式 Lock Mode

  • 共享锁(行锁):Shared Locks
    又称为读锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能写
--加锁方式
select * from student where id = 1 LOCK IN SHARE MODE;
--释放锁
commit/rollback;
  • 排它锁(行锁):Exclusive Locks
    又称为写锁,排它锁不能与其他锁并存,如一个事务获取了一个数据行的排它锁,其他事务就不能再获取该行的锁(共享锁、排它锁),只有获取了排它锁的事务可以对数据进行读取和修改
--加锁方式
自动:delete/update/insert --默认加上X锁
手动:select * from student where id= 1 FOR UPDATE;

意向锁是由数据库引擎自己维护的,用户无法手动操作意向锁

  • 意向共享锁(表锁)简称IS锁:Intention Shared Locks
    表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
  • 意向排它锁(表锁)简称IX锁:Intertion Exclusive Locks
    表示事务准备给数据行加入排它锁,说明事务在给一个数据行加入排它锁前必须先取得该表的IX锁

🤔 思考:为什么需要(表级别的)意向锁?

提高加表锁的效率

锁的作用:解决资源竞争问题

MySQL数据库锁,锁的到底是什么?