一,认识事务
-
原子性:不可分割的工作单位
-
一致性:就是不破坏原本的规则,就是一致,比如主键是唯一的,你事务处理修改主键,主键最后变成了不唯一的,就打破了规则,破坏了一致性。
-
隔离性:并发控制,可串行化,锁,都是这个隔离性,这个事务对其他东西是不可见的,不能被插一脚。
-
持久性:事务一旦提交,是永久性的,能够被恢复。
-
扁平事务:最简单的一种,使用最为频繁,它的操作通过三个命令:begin work;commit work; rollabck work;代表了开始,提交,回滚。回滚就回滚到begin wordk时候的状态,但是这里存在一些大型的事务,回滚到原点,会产生很大的开销,于是产生了一个保存点,可以指定回滚到保存点,对于begin word 其实也是一个保存点,称为保存点0,我们可以再加保存点,它的顺序是递增的,比如1,2,3.我们使用rollback wordk 3,就可以回滚到保存点3,回滚之后,出了0号,其他的事务任然是开启的,所以,任然可以回滚。
-
链事务:保存点事务的变种,当带保存点的事务,在面临系统崩溃重启的时候,只能恢复到开始点,保存点消失了。链事务的思想:提交一个事务的时候,把必要的信息传给下一个事务,(将一个事务的提交和下一个事务的启动合并为一个原子操作),所以链事务的回滚就是直接回滚一个事务,不存在保存点(自然也不存在保存点丢失),而且commit伴随着锁的释放,第一种不会对锁操作(释放锁自认能提高并发)
-
嵌套事务:是一个层次结构框架,树形结构,叶子节点就是扁平事务,而且只有叶子节点才会执行事务操作,InnoDB不支持嵌套事务,但是可以使用保存点扁平事务实现嵌套事务,高层的事务只是进行逻辑控制,决定合适调用相关的子事务。
-
分布式事务:随着业务发展高并发下,就需要多个数据库之间通信了,比如银行跨行转账,(两个银行的数据库不可能在一起吧),那你一个银行的钱-100万,另外一个银行的卡没有+100万怎么办??这就需要分布式业务了。!很重要。(这里没有说基本实现是什么)
二,事务的实现
![](https://i-blog.csdnimg.cn/blog_migrate/9e20a2ee8cda8121e070d6bdd1b16c17.png)
redo log称为重做日志,保证事务的原子性和持久性;undo log用来保证事务的一致性。 两者不是互逆的,redo是恢复提交事务修改页的操作,undo是回滚行记录到某个特定版本。所以两者记录的内容不同,redo是物理日志,记录的是页的修改操作,undo是逻辑日志,根据每行记录进行记录。
三,事务的隔离级别
-
read uncommintted:读未提交,可脏读(直接读内存中的页数据,但是可能没有提交)
-
read commintted:读已提交,别的事务commit,其他马上能读取到(有点像缓存一致性里面嘿嘿),防止脏读,存在幻读。未了控制一致性,可以在sql 末尾加for update保证一致性。
-
repeatable read:可重复读,防止幻读(一会独出来数据是这个,一会是另外一个。。这里的幻读是一个事务里面的幻读,而不是你的全程幻读,为了避免前后数据不一致),需要读取最新数据,那么在当前事务commit之后,再次读取,就可以读取到新数据。它的实现利用的就是undo快照技术。与锁有关系。
-
serializable:串行化,无法并发(效率完全不行),防止死锁。
一,什么是锁
应用为了提高,高并发,又要保证数据安全,所以锁的设计很重要,什么是锁,锁是控制数据处理权限的一种手段,由于sql的存在,所以感觉关系型数据库都大同小异,但是对于锁的实现,每个数据库给出的方案都有很大不同。所以这里要注意区分学习。
对于MYISAM引擎,实现的是表锁设计,并发插入时性能差一些,微软的sql server是页锁,并发性能有所提高,但是对于热点数据无能为力。后来退出了乐观锁和悲观锁,乐观锁是行级锁了。而且锁还会升级
InnoDB锁的实现于Oracle数据库相似,提供一致性的非锁定读,行级锁。
二,lock和latch
latch:门锁,轻量级的锁,(锁的粒度要小,锁的时间短,这样才能支持高并发),在InnoDb中,又分为mutex(互斥量)和rwlock(读写锁)。对象是线程。无死锁机制。
lock:对象是事务,用来锁数据库中的对象,并且lock锁住的对象一般在事务提交或者回滚之后数方。有死锁机制。
三,InnoDB存储引擎中的锁
1,锁的类型:InnoDB实现了两种标准的行级锁:
-
共享锁(S lock):允许事务读一行数据。
-
排他锁(X lock):允许事务删除或更新一行数据。
S只和S兼容,其他两个锁存在,都不兼容的。什么是兼容,就是当t1事务获取r行的共享锁(S),那么t2事务可以获取r行的共享锁,但是不能获得排他锁,要想获得排他锁,就要等待其他事务把r行的锁释放完,才能进行加索。这里就存在阻塞。
对于MyISAM的表锁:上了读锁,本事务只能读取,不能写入,而且不能操作其他表。其他事务只是不能对读锁的表进行写,其他都可以操作,写不会报错,只会阻塞。
InnoDB还支持多粒度锁定,在表,页,记录上面加锁,这种方式称为意向锁(Intention Lock),对行加X锁,需要对库,表,页加上IX锁,最后对行加上X锁。
2.一致性非锁定读:当读取到一个事务在进行update或者delete的时候,不会去等待锁的释放,而是去读该行的快照数据。由undo段完成,
3.一致性锁定读:就是在锁定的情况下,加入..for update 开启一致性。