数据库事务

1. 理解事务

  • 当我们把多个操作打包成一个整体后,这就可以称为一个事务。
为什么需要将多个操作打包成一个整体?

举个例子: 转账

路人甲要将账户里的1000元钱通过网上银行转账到路人乙的账户上。这时就可以分成两个操作:

  • 操作1 : 先从 路人甲 的账户上扣除 1000 元。
  • 操作2 : 再将 路人乙 的账户上增加 1000 元。

注意 :只有当上述的两个操作都执行成功后,才能说转账成功!!!

分析一下上述的问题,我们发现对于 路人甲 和 路人乙 来说,我们只需要两种状态:

  1. 操作1 和 操作2 都执行成功。(从用户的视角出发就是转账成功!)
  2. 操作1 和 操作2 一个都不执行。(从用户的视角出发就是转账失败!)

所以为了避免出现只有一个操作被执行了的情况。我们就需要将这两个操作给打包成一个整体 — 事务

事务的两种状态怎么进行判断?

打包成为事务后,从我们的角度看是只有两种状态的(都执行成功,一个都不执行)。

但是第二种状态:一个都不执行 是怎么去进行判断和处理的???

原来在执行每个事务时,操作都会被依次执行,如果操作全都执行成功,这时就是 第一个状态:事务执行成功。(最后使用 commit 来表示该事务执行成功!)

而如果只有其中的部分操作执行成功了,还有部分操作执行失败了,那么这时就是 第二个状态 : 事务执行失败。(这时就可以使用 回滚(rollback),就相当于进行逆操作,将数据恢复成该事务执行前的状态,这时从我们的视角看来就是 事务的操作一个都没执行

事务的具体使用?

    1. 开启事务:start transaction;
    1. 执行多条SQL语句
    1. 回滚或提交:rollback / commit;

注意:rollback即是全部失败,commit即是全部成功。

示例(回滚)
请添加图片描述
示例(commit)
请添加图片描述

2. 事务的四个基本特性

1. 原子性

这个特性就是上面所说的打包,使多个操作成为一个整体。打包而成的事务只会有两个状态:执行成功(事务中所有的操作都执行成功);执行失败(事务中的所有的操作一个都没执行)。

总结:就是不可再分割的操作。

2. 一致性

这个特性表示,一个事务在执行之前或执行之后,数据库里的数据必须是合理且合法的。

比如: 转账。

转账前和转账后,账户上的钱都不可能是负数。

3. 持久性

当一个事务提交(commit)之后,那么被操作后的数据就必须是持久化的存储在了硬盘上。而不是临时存储的。

4. 隔离性(较为复杂)

总的来说 隔离性 就是描述 事务 在并发执行时,发生的情况!!!(主要是多个事务同时操作同一份数据)

  • 脏读

    • 举个栗子,我这时正在写一篇文章,突然来了一个人,他偷偷瞄了下我的屏幕。然后他看到了文章中所列举的一个例子。他记了下来。后来当我写完这篇文章后,我发现文章中举的例子不合适,所以我就把这个例子给删了,换了一个。这时中途瞄我屏幕的人所拿到的例子和我文章中的例子就不相同 — 这就是脏读问题。

    • 总结:脏读就是一个事务在执行的过程中,另一个事务读取了前一个事务还没有提交的数据,从而不能保证所读取的就是最终结果。

  • 不可重复读

    • 还是上面的例子,我们为了解决脏读问题,所以我们给写操作加锁。这样一来就变成了,我正在写文章,并且不允许其他人来看,直到我提交为止。而那些提前来的人只能等我提交完毕,然后开始读操作。然而这时又有了一个问题,其他人开始读的时候,我又可以进行写操作,这样就导致了一个问题,那就是其他人进行多次读的时候发现前后两次读出的数据不一致。— 不可重复读问题。

    • 总结:不可重复读就是一个事务在进行读操作的过程中,另一个事务又开始进行写操作,从而使读操作中多次读取的数据不一致。

  • 幻读

    • 接着上面的例子,我们就需要把不可重复读的问题给解决掉。通过上面的分析我们发现,问题的出现就是因为读操作时没有进行隔离,使写操作可以执行。所以我们就把读操作也给加上锁。这时就变成了读写操作都有锁的情况。就能把不可重复读的问题给解决了。 但是进行仔细分析后,发现还是会有一个问题:那就是虽然我们已经给读操作和写操作上锁了,但我们是给同一张表中的某几行数据进行上锁的。所以当在进行读操作的时候,写操作可以对其他的行进行操作。这时就会导致一个问题,那就是会使读操作在前后两次读取数据时多几行或者少几行。— 幻读问题。
    • 总结:幻读就是一个事务中进行前后两次读取数据时,发现前后读取数据的集合不同。(多了或者少了)
  • 串行化

    • 由于在上面的例子中出现了 幻读 问题,所以为了解决这种问题,我们只能使用 串行化 执行方式。
    • 串行化:就是一个事务在进行读操作时,另一个事务只能等待。也就是事务依次执行。
    • 总结:串行化就是使事务依次执行,虽然解决了上述的 脏读 、不可重复读 和 幻读 问题,但它的隔离性太高,并发性太低,数据虽然可靠,但是速度最慢。

通过对隔离性的分析,我们发现事务的并发性和隔离性是不可兼得的。注重并发,势必降低隔离性,反之也是如此。所以我们就可以通过不同的隔离级别来控制隔离性和并发性

  • read uncommitted

    允许读取未提交的数据,隔离性最低,并发性最高。会有 脏读、不可重复读、幻读 问题。

  • read committed

    只允许读取提交之后的数据,隔离性提高,并发性降低。会有 不可重复读、幻读 问题。

  • repeatable read

    相当于读和写操作都加锁,隔离性大大提高,并发性大大降低。会有 幻读 问题。

  • serializable

    串行化执行,隔离性最高,并发性最低。解决了 脏读、不可重复读、幻读 问题,但速度最慢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值