数据库事务概览

事务种类

  • 隐式事务

    如单条 sql 语句的执行

  • 显式事务

    如多条 sql 语句的执行,一般谈论数据库事务时,指的是数据库的显式事务

事务特性

数据库事务具有 ACID 这4个特性

  • A —— Atomicity /ˌætəˈmɪsəti/

    原子性。指事务是一个不可分割的工作单元。事务中的操作,要么全部执行,要么全部不执行。这里借用了化学学科的术语概念:原子虽然在物理状态中可以继续细分(原子由原子核和核外电子组成),但原子在化学反应中是不可再分的。

  • C —— Consistent /kənˈsɪstənt/

    一致性。事务必须使数据库从一个一致性状态变换为另外一个一致性状态。比如我的账户余额是 ¥1000,你的账户余额是 ¥2000,两者可以看成一个二元组 (1000, 2000),这代表一个一致性状态。此时,我转账给你 ¥100,并且转账成功了,那么我的账户必定减去了 ¥100,你的账户则必定加上了 ¥100,此时 (1000, 2000) 这个一致性状态变为另外一个一致性状态 (900, 2100)

  • I —— Isolation /ˌaɪsəˈleɪʃn/

    隔离性。即便有多个事务并发执行,每个事务做的操作必须与其它事务隔离。一个事务处理时的中间状态对其它事务是不可见的。

  • D —— Duration /duˈreɪʃn/

    持久性。事务提交后,相关的对数据库数据的修改被持久化存储,接下来的操作和数据库故障不会对其造成其它任何影响。

数据不一致问题

多个并发执行的事务,如果操作时涉及同一条记录数据,可能会发生问题,即并发操作可能导致数据的不一致问题,这些问题包含以下3种情形:

  • 脏读(Dirty Read)

    读取未提交数据

    执行时间事务A事务B
    1事务开启
    2事务开启修改一条记录record
    3读取事务B修改的那条记录(并依据其修改后数据进一步处理,产生未提交的数据依赖关系)
    4事务回滚
    5上一步得到的数据依赖关系是有问题的(比如再次读取事务B修改的那条记录,发现和第3步读取到的数据不一致了)
    6事务提交
  • 不可重复读(Non Repeatable Read)

    前后多次读取,数据内容不一致(数据发生了改变或某些记录已被删除)

    执行时间事务A事务B
    1事务开启
    2读取一条记录record事务开启
    3修改事务A读取的那条记录
    4事务提交
    5再次读取这条记录record(此时发现这条记录跟在同一个事务内之前读取的不一致了,不能重复读)
    6事务提交
  • 幻读(Phantom Read)

    Phantom /ˈfæntəm/ ,一个事务按相同的查询条件重新读取以前检索过的数据,却发现其它事务插入了满足其查询条件的新数据。比如前后多次读取,数据记录总数不一致

    执行时间事务A事务B
    1事务开启
    2查询记录总数count
    3事务开启
    4增加或删除一些记录
    5事务提交
    6再次查询记录总数count(此时count比原来的大了或小了,记录总数变了,幻读)
    7事务提交

隔离级别

为了避免(不是解决)上述可能出现的数据不一致问题,数据库系统提供了隔离级别(Isolation Level)这一机制。
SQL标准定义了4种隔离级别:

  1. Read Uncommitted (可以读取未提交数据)

所有事务都可以读取其他事务所做的更改,即使这些更改并没有提交

  1. Read Committed(可以读取已提交数据)

只有已经提交的更改,其它事务才能读取到

  1. Repeatable Read(可重复读)

比如一个事务,它首先进行了一次查询,这次查询得到了某一行数据的快照,之后如果该事务没有对行的数据内容进行更改,那么该事务内所有对该行数据内容的查询都将以快照的为基准,即使其它事务在该事务读取后立即更改了该行

  1. Serializable(可串行化)

Repeatable Read 差不多,只是禁用了事务的自动提交。它会在任何更新或删除时进行行锁定,并且只能在事务提交后才能进行读取

各种隔离级别分别对应可能出现的数据不一致的情况(Y标志可能出现):

隔离级别(Isolation Level )脏读(Dirty Read)不可重复读(Non Repeatable Read)幻读(Phantom Read)
Read UncommittedYYY
Read Committed-YY
Repeatable Read--Y
Serializable---

隔离级别双刃剑

Read Uncommitted、Read Committed、Repeatable Read、Serializable 这4种隔离级别,按隔离级别严格程度划分,Read Uncommitted隔离级别最低,Serializable隔离级别最严,隔离级别越严格,安全性越高,越能保证数据的一致性,但对并发性能的影响也越大,所谓“鱼与熊掌不可兼得”吧。例如,对于Serializable隔离级别,由于事务是串行执行,即所有事务按照次序依次执行,所以效率会大大下降,应用程序的性能会急剧降低。实际项目使用时需要权衡“利弊”,比如MySQL中的InnoDB引擎,其为了兼顾安全与性能,默认的隔离级别就是Repeatable Read,然后采取隔离级别之外的措施来避免“幻读”的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值