MySql事务笔记

来源:互联网 发布:python socket ttl 编辑:程序博客网 时间:2024/05/04 08:58

事务

事务是一组不可被分割执行的SQL语句集合,如果有必要,可以撤销。银行转账是经典的解释事务的例子。用户A给用户B转账5000元主要步骤可以概括为如下两步。
第一,账户A账户减去5000元;
第二,账户B账户增加5000元;
这两步要么成功,要么全不成功,否则都会导致数据不一致。这就可以用到事务来保证,如果是不同银行之间的转账还需要用到分布式事务。
  

事务ACID

  • 原子性(Autmic):构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。
  • 一致性(Consistency):数据库在事务执行前后状态都必须是稳定的。
  • 隔离性(Isolation):事务之间不会相互影响。
  • 持久性(Durability):事务执行成功后必须全部写入磁盘。

事务隔离

事务的隔离用是通过锁机制实现的,不同于MyISAM使用表级别的锁,InnoDB采用更细粒度的行级别锁,提高了数据表的性能。

InnoDB的锁通过锁定索引来实现,如果查询条件中有主键则锁定主键,如果有索引则先锁定对应索引然后再锁定对应的主键(可能造成死锁),如果连索引都没有则会锁定整个数据表。

mvcc

多版本并发控制是指InnoDB存储引擎通过行多版本的方式来读取当前执行时间数据库中的行数据,简单说就是读不加锁,读写不冲突。这样会极大的增加数据库的并发性能。有人问了,读不加锁,那么写会加锁的啊,这个时候再同时进行读能正常读取吗,答案是肯定的,读取操作不会因为锁没释放而等待,而是会去读取行的一个快照数据(不同事务的隔离级别,访问的快照数据不同)。

针对可能的问题,InnoDB提供了四种不同级别的机制保证数据隔离性。

事务隔离级别

  1. read uncommitted
    READ UNCOMMIT允许某个事务看到其他事务并没有提交的数据。可能会导致脏读、不可重复读、幻读。
    原理:READ UNCOMMIT不会采用任何锁。

  2. read committed
    READ COMMIT允许某个事务看到其他事务已经提交的数据。可能会导致不可重复读和幻读。
    原理:数据的读是不加锁的,但是数据的写入、修改、删除加锁,避免了脏读。

  3. repeatable read(MySQL默认隔离级别)
    可以重复读取,但有幻读。
    原理:数据的读、写都会加锁,当前事务如果占据了锁,其他事务必须等待本次事务提交完成释放锁后才能对相同的数据行进行操作。读取的数据行不可写,但是可以往表中新增数据。
    在MySQL中,其他事务新增的数据,看不到,不会产生幻读。采用多版本并发控制(MVCC)机制解决幻读问题。

  4. serializable
    可读,不可写。SERIALIZABLE 级别在InnoDB中和REPEATABLE READ采用相同的实现。像java中的锁,写数据必须等待另一个事务结束。

其中,Read Uncommited 和 Serializable 比较极端,前一个可以读取未提交的记录,后一个读写冲突,并发性低,所以两者在一般情况下都不建议使用,用的最多是RC和RR。

原创粉丝点击