'事务-分布式事务'
传统事务
事务,即是通过锁控制并发访问。
锁粒度越大,越安全,效率越低;
锁粒度越小,并发高,越不安全。
并发场景:
读读、读写、写读、写写
什么是ACID
原子性(Atomicity)
整个事务,要么全部执行,要么全部不执行。有异常,回滚到执行前状态。
- 记录undo日志,能回滚到之前状态
- 不保证(不一致的)中间结果不被外部看到
一致性(Consistency)
不能破坏关系数据的完整性,以及业务逻辑的一致性。
- 加锁
- 保证中间结果不被外部看到
隔离性(Isolation)==以性能为理由,对一致性的破坏==
持久性(Durability)
事务完成后,改动被持久化存储。不会回滚。
- 磁盘损坏:RAID(保证两块磁盘数据一致,分布式)
- 内存 –> 磁盘:
- 批持久化
- 逐条持久化
- group committed
- 延时提交
- 攒够几个一起提交
读写锁
锁:
- 全局锁(串行化)
- 表级锁
- 数据锁
- 数据读写锁
- 读锁:读数据时加锁,可以并发读。但不能写。
- 写锁:不能并发读,也不能并发写。
数据库隔离级别
隔离级别的存在,提高并发,破坏了一致性。
read uncommitted
- 无读锁、有写锁————读读、读写、写读并行
read committed
- 有读锁、有写锁,读锁可升级为写锁—————读读、读写并行
read repeatable
- 有读锁、有写锁,读锁不可升级写锁—————读读并行
serializable
- 串行化(读时,阻止新数据插入)——————无并行
拓展的隔离级别:snapshot(以上为SQL92标准定义)
当前被映射回SQL92标准的read uncommitted 或者 read committed
- MVCC(当下各流行数据库均有使用)
- 无锁编程
多版本并发控制(MVCC - multi version concurrent control)
核心:copy on write
==优化“写读并发”场景==
- 用新的方式,实现传统意义上read uncommitted场景;同时保证可序列化的隔离级别
- 写多,读少,反而增加系统成本
- 适合读写比率高的场景
拓展(引出的问题):
实现复杂度高。
旧版本数据,什么时候删除。undo log/redo log超长。
常见问题
事务先后
给事务加ID、时间戳。标记事务先后。
故障恢复
业务属性不一致,回滚
需记录事务中,所有操作的反向操作。
数据库崩溃,恢复
先回滚未完成事务,完成后暴露对外访问。
死锁、死锁检测
碰撞检测(高效)
检查事务A请求的锁,被谁持有;持有锁的事务B,又在请求什么锁;该锁刚好被A持有,则判定为死锁。 回滚一个事务即可。
等锁超时
调优原则
- 减少锁的覆盖范围
- 增加锁上可并行的线程数
- 选择正确的锁类型
- 悲观锁
- 使线程到blocking状态(等待被唤醒)
- 导致频繁切换寄存器数据,缓存、cpu cache被清空。换成下一个线程的数据。
- 适用并发争抢严重场景
- 乐观锁
- 适用并发争抢不太严重场景(锁阻塞时间短、请求并发度不高,可以很快抢到锁)
- 悲观锁