文章目录
1事务
1.1什么是事务?
执行过程中的一个逻辑单位 ,包含了多个数据库操作序列组成
1.2 那些存储引擎支持事务
- innodb支持
- MyISAM不支持
1.3事务的四大特性:ACID
原子性:这一组操作要么一起生效,要么都不生效,事务执行过程中如遇错误,已经执行的操作要全部撤回,这就是事务的原子性
一致性:数据库的完成性的约束 就是在执行前数据正确 执行完后数据也正确
隔离性:多个事务共同处理相同数据时,处理是透明的 互不干扰的
持久性:事务只要提交了,它的结果就不能改变了,即使遇到系统宕机,重启后数据库的状态与宕机前一致,这就是事务的持久性
1.4事物发生在什么时候
1.4.1事物开始
1:自动开始
show global variables like “autocommit”;//no:表示 事物默认提交 不用commit也可以提交
set session autocommit=off;
2:手动开始
begin :可以手工开始一个事务
1.4.2结束事物
commit rollback
一个事务持有的锁在其事物结束时才会释放 或者客户端连接中断
1.5事物并发会带来什么问题
1.5.1脏读 select
一个事物前后进行相同的查询 得到数据前后不一样 是因为读取到其他事务未提交的数据 最后其他事物又进行了回滚 那么此时后读取的数据就是脏数据
1.5.2不可重复读update /delete
一个事物前后进行相同的查询 得到数据前后不一样 是因为读取到其他事务以提交的数据 所以此时不可以重复读
1.5.3幻读insert
一个事物前后进行相同的查询 得到数据前后出现了新的数据
1.5.4总结
3大问题都是数据库一致性问题 所以 必须由数据库所提供一定的隔离机制来解决
1.6事物的隔离级别
1.6.1读未提交RU
没有解决任何问题
1.6.2读以提交RC
解决脏读
1.6.3可重复读RR
解决脏读 不可重复读
1.6.4可串行化S
解决 脏读 幻读 不可重复读
缺点: 并发性能太低
- 为什么在innodb中 可以在不可重复读隔离级别时解决幻读问题
2LBCC(基于锁)
在读取数据前 对其加锁 阻止其他事务对数据进行修改
2.1数据库的锁
MyISAM支持:表锁
InnoDB支持:表锁和行锁
2.2锁的基本分类
2.2.1共享锁
又称读锁 多个事物对于同一个数据可以共享一把锁 但只能读不能修改
加锁方式 :select * from tablename where id =1 LOCK IN SHARE MODE ;
释放锁:commit/rollback
2.2.2排他锁
又称写锁 多个事物对于同一个数据不可以共享一把锁 可以对数据进行读取和修改
加锁方式 :
自动:delete /update /insert
手动: select * from tablename where id =1 FOR UPDATE;
释放锁:commit/rollback
2.2.3意向锁
是由数据库引擎自己维护的 用户无法手动操作意向锁 当用户给一行数据加一个意向锁时 那么这张表就得取得(加上)表的意向锁
层次越高的锁(如表锁),可以有效减少对资源的占用,显著减少锁检查的次数,但会严重限制并发。层次越低的锁(如行锁),有利于并发执行,但在事务请求对象多的情况下,需要大量的锁检查。数据库系统为了解决高层次锁限制并发的问题,引入了意向(Intention)锁的概念:
2.3锁的原理
== 锁到底锁住了什么?锁住了索引==
- 不使用索引:此时锁锁住了所有了隐藏索引 就相当于锁住了表
- 主键索引:聚集索引
- 唯一索引:辅助索引(非聚集索引)
2.4行锁的算法
2.4.1 区间定义
2.4.2记录锁
2.4.3间缝锁
2.4.4临键锁(默认)
2.4.5总结
为什么Innodb在可重复读隔离级别 解决了幻读问题 因为使用了临键锁,在一个事物在操作一个范围时对齐范围进行了锁定 另一个范围就无法操作 就没有了幻读问题
3MVCC(多版本)
1基本概念
- MVCC只支持读以提交和可重复读两种隔离机制级别
- 数据库维护了一条记录的多个物理版本。事务写入时,创建写入数据的新版本,读请求依据事务/语句开始时的快照信息,获取当时已经存在的最新版本数据。 它带来的最直接的好处是:写不阻塞读,读也不阻塞写,读请求永远不会因此冲突失败(例如单版本T/O)或者等待(例如单版本2PL)。对数据库请求来说,读请求往往多于写请求。主流的数据库几乎都采用了这项优化技术。
- 如果我想要我在一个事务中读取的结果一致时 干脆在第一次读取的时候就叫结果缓存起来 这个结果就叫快照 以后就只需要操作这个快照就可以了 ,这样就保证了一个事务中数据的一致性
3.2先说下表中一行隐藏的3列
- DB_TRX_ID :事物ID 每次处理加1
- DB_ROLL_PTR:指向undo log的一个指针
- DB_ROW_ID:索引中的ID
3.3MVCC下 数据更新的过程
- 先用排他锁锁住改行
- 先将修改的行复制一份 然后放在undo log中
- 然后将改行的DB_ROLL_PTR指针指向undo log中的改行快照 并将DB_TRX_ID+1;
- 然后对数据进行修改 name 张三–>李四
3.4 版本链对比规则
用nudo log 中的版本链中每条版本记录的事务ID进行下面三个区间的匹配
- 当前事物ID<最早事物mid_id :表示这个版本是由以提交的事物生成的 这个数据是可见的
- 当前事物ID>最晚事物max_id:表示 这个版本是由将来的事务生成的 这个数据是不可见的
- 最早事物ID<当前事物ID 最晚事物ID:分两种情况
- row的trx_id在undo log的链表中 表示这个版本的是由还没有提交的事务生成的 不可见 当前自己的事务可见
- row的trx_id不在undo log的链表中 表示这个版本的是由提交的事务生成的 可见
3.5总结
MVCC是读和写请求的优化技术,没有完全解决数据库并发问题,它需要与前述的几种并发控制技术组合,才能提供完整的并发控制能力。常见的并发控制技术种类包括:MV-2PL,MV-T/O和MV-OCC,它们的特点如下表: