事务
事务其实就是一组DML语句的集合,MySQL数据库InnoDB存储引擎支持事务,MyISAM不支持,而且MySQL的事务默认是自提交模式。
事务的特性
- 原子性:事物的原子性是指包含所有的操作,要不然全部都做,要不然全部都不做,他是一个不可以被打断的过程。
- 一致性:一致性是说数据库中的数据在事务操作前和操作后必须满足业务规则的约束。
- 隔离性:这个是我们的重点,隔离性是数据库允许多个并发事务同时对数据进行读写或者修改的能力,因为事务具有原子性,所以不会由于交叉执行带来的数据不一致问题。
事务语句
接下来我们来看看基础的事务语句,首先开启事务是由begin或者start transaction命令来开始的,当我们把自提交性关掉后(set autocommit = 0)。事务结束通常使用commit或者rollback,其中的区别是commit代表永久的写入事务带来的修改,而rollback代表回滚,撤销正在执行的修改。
如上图所示这是一个正常的事务流程
上图是回滚的用法, 可以看出这一条插入语句并没有起作用。
我们知道MySQL数据库是自动提交的模式,那么我们到底需不需要设置这个自动提交呢,当我们关闭自动提交的时候,不用一个一个的提交了,而是多个事务一起提交,提高了每一秒处理事务的能力,但是相应的如果在这个过程中某个事务一直没有被提交,就会导致行锁等待的现象,其他事务必须等待这个事务提交之后才会继续提交,这样就会严重的影响TPS。
事务的隔离级别
MySQL InnoDB存储引擎实现的有四种隔离级别,用来限定事务内外的那些改变是可见的,那些是不可见的。低级别的隔离性一般支持更高的并发处理,并拥有更低的系统开销。
查看隔离级别的语句是
show variables like '%tx_isolation%';
- 读未提交:简称RU,在其中一个事务中,可以读取到其他事务未提交的数据变化,这种读取其他会话还没提交的事务,叫做脏读现象,在生产环境中不建议使用。
- 读已提交:简称RC,在其中一个事务中,可以读取到其他事务已经提交的数据变化,这种读取也叫做不可重复读,是Oracle数据库默认的事务隔离级别。
- 可重复读:简称RR,在其中一个事务中,直到事务结束前,店铺可以反复读取到事务刚开始看到的数据,并不会一直发生改变,避免了脏读,幻读等现象,也是MySQL的事务隔离等级。
- 串行:在每个读的数据上都需要加上表级共享锁,每次写数据的时候都需要加上排他锁,造成了InnoDB的并发能力下降,大量超时和锁竞争就会产生,虽然足够安全但是不建议使用。
锁
数据库锁机制简单来说,就是为了保证数据的一致性,让各种共享资源并发时变得有序的一种规则。
MySQL的锁机制比较简单,各种不同的引擎拥有不同的锁机制,InnoDB支持行锁,有时也会升级为表锁。但是MyISAM只支持表锁。
表锁的特点是开销小,加锁快,不会出现死锁,颗粒度大,发生锁冲突的概率大。
行锁的特点是开销大,加锁慢,会出现死锁,颗粒度小并且发生锁冲突的概率小。
InnoDB的锁类型主要有读锁,写锁,意向锁和MDL锁。
读锁
读锁简称S锁,当一个事务获得了某一个数据行的读锁的时候,其他事务可以读该数据行但是不能对该数据行进行写操作。
写锁
写锁简称X锁,一个事务获取了一个数据行的写锁,其他事务就不能在获取该数据行的其他锁,写所得优先级最高。一些DML语句操作都会加写锁。
MDL锁
MDL锁用于保证表中元数据的信息,在会话A中,表开启了查询事务后,会自动获得一个DML锁,会话B就不可以执行任何DDL语句的操作。