数据库之事务
事务:指的一组操作,里面有许多单一的逻辑。只要有一个逻辑没有执行成功,就算失败。所有的数据都回归到最初的状态(rollback)
- 为什么要有事务
为了确保逻辑的成功
- 开启事务 start transaction
- 提交或回滚事务 commit:提交事务,数据会写到磁盘上的数据库中 rollback:数据回滚,回到最初始状态
事务的特性(ACID)
- 原子性
指的是 事务中包含的逻辑,不可分割
- 一致性
指的是 事务执行前后。数据完整性
- 隔离性
指的是 事务执行期间不应该受到其他事务的影响
- 持久性
指的是 事务执行成功后,数据应该保存到磁盘上
事务的隔离级别
读未提交
引发问题:脏读
读已提交
解决:脏读 引发:不可重复读
可重复读
解决:脏读,不可重复读 未解决:幻读
可串行化
解决:脏读,不可重复读,幻读
mysql的默认隔离级别:可重复读
Oracle的默认隔离级别:读已提交
事务的安全隐患
不考虑隔离级别(读未提交,读已提交,可重复读,可串行化)设置,那么会出现以下问题
-
读
- 脏读:一个事务读到另外一个事务还未提交的数据
- 设置A窗口的隔离级别 *读未提交
- 两个窗口都分别开启事务
- A窗口修改数据还没提交,B窗口select数据就是脏数据(不正确的)
- 不可重复读 :只能读取到其他事务已经提交的数据,哪些没有提交的数据是读不出来的。会造成前后读取的结果不一样。不可重复读指的是不能执行多次读取,否则会出现结果不一。
- 设置A窗口的隔离级别为 读已提交
- AB两窗口都开启事务,在B窗口执行更新操作
- 在A窗口两次查询数据不相同,一次是在B窗口提交事务之前,一次是在B窗口提交事务之后
- 这个隔离级别能够屏蔽脏读现象,但是引发了另一种现象,不可重复读
- 幻读:一个事务读到另外一个事务insert的数据
- 如果有一个连接的隔离级别设置为了可串行化。那么谁先打开了事务,谁就有了先执行的权利。谁后打开了事务,就必须等待前面的事务提交或者回滚后,才能执行。但是这种级别比较少用,因为会造成性能上的问题。效率比较低
- 脏读:一个事务读到另外一个事务还未提交的数据
-
写
-
丢失更新
- B事务如果提交,那么会造成修改的姓名没有了
- B事务回滚,那么会造成A想更新的数据没有。因为B记得自己拿出来的数据是lisi 1000
-
解决方案,锁机制
-
悲观锁:select * from account for update。只要当A的更新提交了,B才能再一次查看数据,未提交查看界面卡住。
-
乐观锁。A事务先提交,数据库version变为1;B在提交的时候比对数据库version,不一样则不允许提交,要先更新。
-
-