数据库之事务一览


  • 事务的ACID属性
  • 5种状态
  • 隔离级
  • 事务隔离性中出现的几种问题
  • 不同数据库支持的隔离级别

事务

在数据库中事务是工作的逻辑单元,一个事务由一个或多个完成相关行为的SQL语句组成,通过事务机制保证这一组SQL语句所做的操作要么全部执行执行成功,要不全部不执行

事务的ACID属性

  1. 原子性(Atomicity)
    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  2. 一致性(Consistency)
    事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

  • 比如:转账,假设用户A和用户B两者的钱加在一起是1000元,那么不管A和B之间如何转账,转几次帐。事务结束后两个用户的钱加在一起还得是1000
  1. 隔离性(Isolation)
    事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,即并发执行的各个事务之间不能互相干扰。

  2. 持久性(Durability)
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。


5种状态

  1. 活动状态(active)
    事务在执行时的状态叫活动状态。

  2. 部分提交状态(Partial Committed)
    事务中最后一条语句被执行后的状态叫部分提交状态。

  3. 失败状态(Failed Committed)
    事务不能正常执行的状态叫失败状态。

  4. 提交状态(Committed)
    事务在部分提交后,将往硬盘上写入数据,当最后一条信息写入后的状态叫提交状态。进入提交状态的事务就成功完成了。

  5. 中止状态(Aborted)
    事务回滚并且数据库已经恢复到事务开始执行前的状态叫中止状态。


隔离级别

于是数据库定义了4种隔离级:
ANSI/ISO SQ92标准:

隔离级别描述
READ UNCOMMITTED(读未提交数据)允许事务读取未被其他事务提交的变更,脏读、不可重复读和幻读的问题都会出现
READ COMMITED(读已提交数据)只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然会出现
REPEATABLE READ(可重复读)确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题\依然存在
SERIALIZABLE(串行化)确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可以避免,但性能十分低

以及其分别可能出现的问题,级别越高其效率也就越低

隔离级别脏读不可重复度幻读
read uncommitted ✓ \checkmark ✓ \checkmark ✓ \checkmark
read CommittedX ✓ \checkmark ✓ \checkmark
repeatable readXX ✓ \checkmark
serializableXXX

事务隔离性中出现的几种问题

对于不同的隔离级别有不同的隔离问题:

  • 脏读: 是指一个事务处理过程读取了另一个未提交事务中的数据 。
    即当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。

  • 不可重复读:是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

例如,事务A在读取某一数据,而事务B立马修改了这个数据并且提交事务给数据库,事务A再次读取该数据就得到了不同的结果,发生了不可重复读。

注 : 不 可 重 复 读 和 脏 读 的 区 别 是 , 脏 读 是 某 一 事 务 读 取 了 另 一 个 事 务 未 提 交 的 脏 数 据 , 而 不 可 重 复 读 则 是 读 取 了 前 一 事 务 提 交 的 数 据 。 \textcolor{Red}{注:不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交\\的脏数据,而不可重复读则是读取了前一事务提交的数据。 }

  • 幻读:是指在两个连续的查找之间一个并发的修改事务修改了查询的数据,导致这两个查询返回了不同的结果。是事务非独立执行时发生的一种现象。

例如事务A,对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务B又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务A的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务B中添加的,就好像产生幻觉一样,这就是发生了幻读。

又或者事务A和事务B:
事务B查询表中的数据特定条件的数据,刚查完所有满足的记录,此时事务A有添加了几条满足条件的记录,并提交的事务,如果事务B再次查询,就会查询出比上次更多的结果。

幻 读 和 不 可 重 复 读 都 是 读 取 了 另 一 条 已 经 提 交 的 事 务 ( 这 点 就 与 脏 读 不 同 ) , 所 不 同 的 是 不 可 重 复 读 查 询 的 都 是 同 一 个 数 据 项 , 而 幻 读 针 对 的 是 一 批 数 据 整 体 ( 比 如 数 据 的 个 数 ) 。 \textcolor{Red}{ 幻读和不可重复读都是读取了另一条已经提交的事务(这点就与脏读不\\同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(\\比如数据的个数)。}


不同数据库支持的隔离级别

  • 对于Oracle支持的隔离级别:
    ORACE提供了SQ92标准中的read committed和seriaizabe,同时提供了非SQ92标准的read-ony。默认级别是read committed。
    注 : s e r i a l i z a b l e 仅 仅 能 看 见 在 本 事 务 开 始 前 由 其 它 事 务 提 交 的 更 改 和 在 本 事 务 中 所 做 的 更 改 . r e a d − o n l y 仅 仅 能 看 见 在 本 事 务 开 始 前 由 其 它 事 务 提 交 的 更 改 和 在 本 事 务 中 所 做 的 更 改 。 \textcolor{Red}{注:serializable 仅仅能看见在本事务开始前由其它事务提交的更改和\\在本事务中所做的更改. \\ read-only 仅仅能看见在本事务开始前由其它事务提交的更\\改和在本事务中所做的更改。} serializable.readonly

Oracle数据库的隔离级别

  • Mysql支持的隔离级别:
    就是以上四种。默认是最低级。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值