欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈数据库之事务

程序员文章站 2024-01-14 09:24:34
...

文章首发于个人博客,欢迎访问关注:https://www.lin2j.tech

事务是数据库管理系统执行过程的一个逻辑单位,由有限的数据库操作序列构成
四个特性:

  • 原子性(Atomicity):事务被视为最小操作单元,其中的操作要么全部成功,要么全部失败。
  • 隔离性(Isolation):事务所做的修改在最终提交之前对其他事务是不可见的。
  • 一致性(Consistency):数据库在执行事务前后保持一致性的状态,在一致性状态下,所有事务对数据库的读取都是同一个结果。即事务的中间状态对其他事务不可见。只有数据的初始状态和终止状态可见。
  • 持久性(Durability):一旦事务提交,则其所做的修改都会永远保存在数据库中,及时数据库损坏,也可以通过日志还原数据库,保证持久性。

一致性和原子性的区别,原子性注重操作的状态,要么全部成功,要么全部失败。一致性注重数据的可见性,数据的中间状态不可见,只要头尾可见。
这是我目前的理解,我发现四个特性还是有点东西的。理解的不对,欢迎指出。


并发下可能发生的事务问题

并发环境下,事务的隔离性难以保证,事务的一致性就会遭到破坏

  1. 丢失修改:事务T1修改一个数据A=10后,事务T2紧接着也修改了A=20,T1再来读取A时,发现不是 10 而是 20。T1写了个寂寞。
  2. 脏读:事务T1修改了一个数据A=10后,事务T2紧接着读取这个数据A,如果此时T1再撤销对A的修改,那么T2读到的这个数据将是错误的,无意义的。T2读了个寂寞。
  3. 不可重复读:事务T2读取数据A,得到10,然后T1修改了A=20,此时T2再来读取A时,发现得到的不是预想的10,而是20。T2有点懵逼。
  • 产生并发问题主要的原因是事务的隔离性没有控制好,导致一致性不能得到保证,因此可以通过并发控制来保证隔离性。数据库管理系统提供了事务的隔离级别来处理并发时的一致性问题。
事务的隔离级别

推荐一篇文章理解不同事务隔离级别的表现

  1. READ_UNCOMMITTED(未提交读):最低级别的隔离,允许其他事务读取尚未提交的数据变更,会导致不可重复读,脏读。
  2. READ_COMMITTED(提交读):允许其他事务读取已经提交的数据,可以防止脏读,但还是可能有幻读、不可重复读。(Oracle 默认)
  3. REPEATABLE_READ(重复读):对同一字段的多次读取结果是相同的,除非数据是被本身事务修改的。可以防止脏读,不可重复读,但还可能有幻读。
  4. SERIALIZABLE (串行):*别的隔离。所有事务逐个执行,不存在事务之间的相互干扰,可以防止脏读、不可重复读、幻读。但是因为是串行执行的,数据库的性能也会有所下降。
  • MySQL中查看隔离级别
    select @@tx_isolation;
    
  • 设置事务的隔离级别
    set tx_isolation="隔离级别名称";
    
  • 各种隔离级别的锁的粒度
    • 提交读:锁住行。
    • 可重复读:如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key锁,如果检索条件没有索引,更新数据时,会锁住整张表,其他事务是不能再这个间隙插入记录。
    • 串行化:锁住整个表。
      浅谈数据库之事务
并发控制

传送门

相关标签: 数据库