MySQL
事务
- 手动开启事务:start transaction
- MySQL的是默认提交事务的,查看是否是默认事务
- select @@autocommit;
- set @@autocomiit = 0; --设置成手动提交
- 默认提交的1
- 事务的四大特征
- 原子性:一个事务,要么成功,要么失败
- 持久性:事务提交或回滚后,数据库会持久化的保存数据到硬盘
- 隔离性:多个事务之间,相互独立
- 一致性:事务操作前后,数据总量不变
- 事务的隔离级别
- 概念:多个事务之间,相互独立,但是如果多个事务操作同一批数据,设置不同的隔离级别可能会导致一些问题:
- 脏读:一个事务,读取到另一个事务中还未提交的数据
- 不可重复读:一个事务,两次读取到的数据不一致
- 幻读:一个事务操作(DML)了数据表中的所有记录,另一个事务添加了一条数据,则第一个事务查不到自己的修改
- 四大隔离级别
- read uncommitted:读未提交
- 可能会导致脏读、不可重复读、幻读
- read committed:读以提交(Oracle默认)
- 可能会导致不可重复读、幻读
- repetable read:可重复读(MySQL默认)
- 可能会导致幻读
- serializable:串行化(实际上就是锁)
- 解决所有问题
因为事务的隔离级别的安全性是从小到大越来越高,但是效率越来越低,因此不使用最后一个级别
- 设置隔离级别:
- 先查询隔离级别:select @@tx_isolation;
- 设置隔离级别:set global transaction isolaton level 级别字符串;
- 理解脏读:事务A和事务B,事务A对数据进行了修改,还未提交,事务B就对数据进行了访问,事务B访问到数据后,事务A回滚了,事务B再操作的就是脏读数据
- 不可重复读:事务A修改后,提交了,事务B访问两次读取到的数据不一致
- 幻读:MySql体现不出来
- serialiable:如果事务A对数据操作时,事务B访问数据时,访问不出来。只有事务A提交事务后,事务B才能访问出来,因此这个级别效率太低了
锁机制
- MySQL的锁主要有乐观锁和悲观锁,悲观锁又有行锁,读写锁,表锁等
- 乐观锁:乐观锁是认为在每次操作数据时不会有其他操作出现,因此不会上锁,在操作时会查看一下有没有其他操作对数据进行更新。如果有更新则放弃操作,没有则继续。
- 悲观锁:悲观锁是悲观认为每一次操作都会引起冲突,因此会给每次操作加上锁。
- 行锁:又可分为读锁(共享锁)和写锁(排他锁)
- 读锁:一个事务在读取一行数据时,加上读锁,防止其他事务对其数据加排它锁。事务1加上读锁后,多个事务只能读取数据而不能修改数据。
- 写锁:一个事务在给数据加上写锁后,可以对数据进行读取和写入,其他事务不能对该数据加锁知道事务释放写锁。
- 悲观锁和乐观锁的区别
- 两个锁的使用场景不同,悲观锁适合在冲突高的操作场景下并发量高时适合用悲观锁,即一个人操作,另一个人不能操作。乐观锁则是给加上状态码,很适合多读的场景
- 效率上不一样,悲观锁对于执行效率减弱,乐观锁效率高,吞吐量高
- 乐观锁的实现方式
- 添加版本号:以version标识操作,如果有操作发生version加1,则判断操作前的version是否与后查询出来的version字段相同
- CAS算法