目录
分布式事务
事务的特性
ACID
原子性:
数据库的操作,要么全部完成,要么全部不完成 经典例子 转账 我减钱 你加钱 要么都完 成 ,要么都不完成 底层是通过 undo日志实现的
一致性
数据写入前后,数据库的完整性没有被破坏,即写入的数据符合约束 触发器 级联回滚。。
隔离性
数据库允许,多个事务同时进行,隔离性可以防止多个事务并发执行时由于交叉执行而导致的数据不一致 事务隔离级别 包括 未提交读,提交读,可重复读,串行化
底层通过锁和MVCC实现
持久性
事务处理后,对数据的修改就是永久的,出现系统故障也不会丢失
事务并发带来的问题
多个事务 可能 会对相同的数据 进行curd
更新丢失(脏写)
场景描述
A和B 两个事务 都是 同时向 张三转钱
A 向张三 转100 B 向 张三转 200
正常: 张三现在应该有 300
假如 A和B是同时 获得了 张三 现在有0元
A将100写进去了
但是由于 A和B 是隔离的
B 不知道 A更改了 它要修改的数据
导致 B 将 200写进去 了 最后 数据库 张三只有 200块
解决方法:
让A和B顺序执行 串行化
脏读
场景描述
A向张三 转 100快
B问张三多少钱
A将100快转给张三后,再要提交事务前,
B 读取到 张三 有100
但是A出现了异常,导致回滚
最后 张三没有钱,但是A却读到了100
解决方法
先写后读,也就是写完再读
不可重复读
场景描述:
张三 15岁
A:想要将张三的年龄修改为 20岁
B:想要查询张三的年龄
B查到 张三的年龄 是15 感觉到不可思议
又查了一次 查询之前 A将 张三的年龄 修改为20了
B又查到了20岁
B的两次查询不一致
解决方法
先读后写
幻读
场景描述:
A:想要将 添加 一个 张三的信息
B:想要查询张三
B 差不到张三 感觉到不可思议
又查了一次 查询之前 A将 成功的将张三添加进去了
B又查到了张三
B的两次查询不一致
解决方法
先读后写
幻读 和 不可重复读的区别
幻读的操作是插入
不可重复读 是操作是 更新和删除
事务隔离级别 默认RR
读未提交(RU)
事务可以读取到未提交的数据 会有脏读 不可重复的 幻读
两个事务 并发 执行 时
A 事务 可以 读取到 B 事务未提交的数据
读已提交(RC)
事务只能读取到已经提交的数据 会有 不可重复的 幻读
两个事务 并发 执行 时
A 事务 可以 读取到 B 事务已提交的数据
行锁
当 两个事务 并发 执行 时
B事务 更新 了 一条数据 , 如果这个事务没有 提交 ,其他的事务再来修改这个数据,就会死锁
可重复读(RR)
再同一个事务内,多次读取同一数据是一致的 可以解决 不可重复的 会有幻读
串行化
将所有事务 进行 串行 解决了所有
一个事务再执行 另一个 事务就会阻塞