MySQL-事务简介

事务的特性

ACID即原子性,一致性,隔离性,持久性

  • **原子性(Atomicity):**原子的概念就是不可分割,你可以把它理解为组成物质的基本单位,也是我们进行数据处理操作的基本单位。
  • **一致性(Consistency):**数据库在进行事务操作后,会由原来的一致状态,变成另一种一致的状态。也就是当事务提交后,或者当事务发生会滚后,数据库的完整性约束不能被破坏。
  • **隔离性(Isolation):**每个事务都是彼此独立的,不会受到其他事务的执行影响,也就是说一个事务在提交之前,对其他事务都是不可见的。
  • **持久性(Durability):**事务提交之后对数据的修改是持久性的,即使在系统出故障的情况下,数据的修改依然有效的。因为当事务完成,数据库的日志就会被更新,这时,可以通过日志,让系统恢复到最后一次成功更新的状态。

原子性是基础,隔离性是手段,一致性是约束条件,持久性是我们的目的。

隔离性-隔离级别

异常

  1. **脏读dirty read:**读到了其他事务还没有提交的数据。

    事务A事务B
    开启事务A开启事务B
    执行SELECT v FROM T WHERE id = 1 得到结果 v=1
    执行update t set v = v + 1 where id = 1
    再次执行SELECT v FROM T WHERE id = 1 得到结果 v=2
    提交事务B
  2. **不可重复读non-repeatable read:**对某数据进行读取,发现两次读取的结果不同,也就是说没有读到相同的内容,这是因为有其他事务对这个数据同时进行了修改或者删除。

    事务A事务B
    开启事务A开启事务B
    执行SELECT v FROM T WHERE id = 1 得到结果 v=1
    执行update t set v = v + 1 where id = 1
    提交事务B
    再次执行SELECT v FROM T WHERE id = 1 得到结果 v=2
  3. **幻读phantom read:**事务a根据条件查询得到了n条数据,但此时b事务更改或者新增了M条符合事务a查询条件的数据,这样当事务a再次进行查询的时候发现会有m+n条记录,产生了幻读。

    事务A事务B
    开启事务A开启事务B
    执行SELECT v FROM T WHERE id < 10 得到的结果集条数假设为5条,其中id有 1,2,3,4,5
    执行insert into T (id,v) values (6,10)
    提交事务B
    执行SELECT v FROM T WHERE id < 10 得到的结果集条数为6条,其中多了一条id=6的结果集

隔离级别

  • **读未提交read uncommitted:**一个事务还没提交时,它做的变更就能被别的事务看到。这种情况下,查询是不会使用锁的,可能会产生脏读,不可重复读,幻读等情况。
  • **读提交read committed:**一个事务提交之后,它做的变更才能被别的事务看到。可能会产生不可重复读,幻读。想要避免,需要编写带锁的sql语句。
  • **可重复读repeatable read:**一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据一致。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。无法避免幻读。
  • **串行化serializable:**对于同一行记录,写会加写锁,读会加读锁。当出现读写锁冲突时,后访问的事务必须等前一个事务执行完成,才能继续执行。可以解决事务读取中所有可能出现的异常情况,但是牺牲了系统的并发性。
脏读不可重复读幻读
读未提交
读提交×
可重复读××
串行化×××

×:表示不可能产生的问题

√:表示可能会产生的问题

事务A事务B
开启事务A,执行select v from T where id = 1;,得到值,记为V1开启事务
执行update T set v = v + 1 where id = 1将1改成2
再次执行select,查询得到的值记为V2
提交事务
再次执行select,查询得到的值记为V3
提交事务
再次执行select,查询得到的值记为V4
  • 读未提交,则v1=2,这时候事务B虽然没有提交,但是结果已经被a看到了,因此,v2=2,v3=2,v4=2;
  • 读提交,v1 = 1,v2=1。事务b的更新也是在提交后才能被a看到,所以v3=2,v4=2;
  • 可重复读,v1 = 1,v2=1,v3=1,v4 =2之所以v2=1,v3=1,遵循的是:事务在执行期间看到的数据前后必须是一致的。
  • 串行化,事务b执行将1变成2的时候,会被锁住,直到a提交后,b才能继续执行,所以从a的角度,v1 = 1,v2 = 1, v3 = 2,v4=2;

事务控制相关语句

  1. start transaction或者begin,作用是显式开启一个事务。
  2. commit:提交事务,当事务提交后,对数据库的修改是永久性的。
  3. rollback/rollback to [savepoint]:撤销正在进行的所有没有提交的修改,或者将事务会滚到某个保存点。
  4. savepoint:在事务中创建保存点,方便后续针对保存点进行回滚,一个事务中可以存在多个保存点。
  5. release savepoint:删除某个保存点。
  6. set transaction:设置事务的隔离级别。
    oracle默认是不自动提交,Mysql是默认自动提交,可以修改
set autocommit = 0;-0是关闭,1是开启
set @@comletion_type = 1;
  1. comletion_type=0:这是默认情况,也就是当我们执行commit的时候会提交事务,在执行下一个事务时,还需要我们使用start transaction或者Begin来开启。
  2. comletion_type=1: 当我们提交事务后,相当于执行了commit and chain,也就是开启了一个链式事务,即当我们提交时候之后会开启一个相同的隔离级别的事务。
  3. comletion_type=2: commit and release,会自动与服务器断开连接。

注意

1.oracle数据库的默认隔离级别是读提交,mysql默认的是可重复读。因此对于一些从oracle迁移到mysql的应用,为保证数据库隔离级别的一致,一定要记得将mysql的隔离级别设置为读提交。
配置方式是将启动参数transaction_isolation设置为READ_COMMITTED;

show variables like ‘transaction_isolation’;

2.幻读和不可重复读的区别

  • 幻读的在新增或者删除行记录的时候产生的现象,导致两次读取的记录条数不一致。
  • 不可重复读是由于修改了某条数据,导致两次读取的数据不一致。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值