MySQL事务

事务的基本概念

在这里插入图片描述

一个事务是由一条或者多条SQL语句所组成的一个不可分割的单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库;如果有部分事务处理失败,那么事务就要回退到最初的状态,因此,事务要么全部执行成功,要么全部失败。

记住事务的几个基本概念:

  1. 事务是一组SQL语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果,必须保证事务执行的原子操作
  2. 事务的所有SQL语句全部执行成功,才能提交(commit)事务,把结果写回磁盘上。
  3. 事务执行过程中,有的SQL语句执行出现错误,那么事务必须要回滚(rollback)到最初的状态。(undo log,回滚日志

事务的ACID特性

每一个事务必须满足下面的4个特性:

  • 原子性(Atomic)

    事务是一个不可分割的整体,事务必须具有原子性,即当数据修改时,要么全执行,要么不执行,即不允许只完成部分。

  • 一致性(Consistency)

    一个事务执行之前和执行之后,数据库数据必须保持一致性状态,数据库的一致性状态由用户来负责,由并发控制机制来实现,就拿网上购物来说,只有让商品出库,并且让商品进入购物车才能构成一个完整的事务。

  • 隔离性(Isolation)

    当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事务内部的操作与其他事务的操作隔离起来,不被其他正在执行的事务所看到,使得并发执行的各个事务之间不能互相影响。

  • 持久性(Durability)

    事务完成(commit成功)后,DBMS(关系型数据库管理系统)保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据---->redo log(重做日志)

    先将数据写到cache缓存上,然后再通过磁盘I/O,慢慢往磁盘上写数据,需要注意commit提交事务后,就返回了,而从cache往磁盘上写是要花费时间的,对于应用程序来说,commit提交成功就代表了成功修改了数据,但是如果由于一些不可抗因素,比如服务器停电、宕机或者重启,那么很有可能cache中的数据还没有完全写到磁盘上,redo log(重做日志)能保证数据库的永久性!

    mysql最重要的是日志,而不是数据

    事务的ACD特性是由mysql的redo log和undo log来保证的

    事务的I(隔离)特性是由mysql事务的锁机制+MVCC来实现的


事务并发执行存在的问题

事务处理不经隔离,并发执行时通常会发生以下问题:

  • 脏读(Dirty Read):一个事务读取了另一个事务未提交的数据,例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交数据,此时事务A回滚,则事务B读取到的数据就是无效的脏数据(事务B读取了事务A尚未提交的数据这种情况是我们必须去避免的!

  • 不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读取到不同的数据,例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A的更新操作更改了事务B查询到的数据,此时事务B再次去读取该数据,发现前后两次读的数据不一样(事务B读取了事务A已提交的数据)-----可杜绝,也可以不杜绝,具体看业务的需求

  • 虚读(Phantom Read):一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如,当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一天满足事务B查询条件的记录,此时B再去查询,发现查询到前一次不存的记录或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)-----根据具体业务需求,看是否需要杜绝


事务的隔离级别

MySQL支持的四种隔离级别:

  • TRANSACTION_READ_UNCOMMITTED。未提交读,说明在提交前一个事务可以看到另一个事务的变化。这样读脏数据,不可重复读和虚读都是被允许的
  • TRANSCATION_READ_COMMITTED。已提交读。说明读取未提交的数据是不允许的(事务B不能读取事务A未提交的数据),这个级别仍然允许不可重复读和虚读产生(Oracle默认工作在以提交读隔离级别)
  • TRANSCATION_REPEATABLE_READ。可重复读,在这些宏隔离级别下事务保证能够再次读取相同的数据而不会失败(其他事务对数据的修改并不会体现在当前事务上,只要当前事务不进行修改,那么事务读取的一直是原始的数据),但虚度仍然会出现(MySQL默认工作在可重复读隔离级别)
  • TRANSCATION_SERIALIZABLE。串行化,是事务的最高隔离级别,它防止脏读、不可重复读以及虚读。

在这里插入图片描述

事务的隔离级别越高,为避免冲突所花费的性能开销也就越多

在可重复读级别下,一定情况下(insert,delete)是可以解决虚读问题的,但是对于update并没有解决虚读问题
在这里插入图片描述

可以看到在隔离级别为TRANSCATION_REPEATABLE_READ下,左边的事务A即使对表中数据做了修改(update),事务B前后两次的查询结果是一致的,说明确实支持数据的可重复读,并且可以看到事务A先在表中插入了新的记录,但是事务B读取的依然是此前的数据,说明实际上可重复读级别下,是一定程度上可以解决虚读问题的,但是如果事务B中我们使用update去更新事务A中插入的记录,又可以更新成功,说明对于update,可重复级别无法解决虚读问题。


MySQL的事务处理命令

  1. 查看MySQL是否自动提交事务
select @@autocommit;

在这里插入图片描述

0表示手动提交事务,1表示自动提交事务,设置事务提交方式为手动提交方式:

set autocommit;

在这里插入图片描述

Begin:开启一个事务

COMMIT:提交一个事务

ROLLBACK:回滚一个事务到初始的位置

SAVEPOINT point1:设置一个名字为point1的保存点

ROLLBACK TO point1:事务回滚到保持点point1,而不是回滚到初始状态

  1. 设置事务的隔离级别
SET TX_ISOLATION='REPEATABLE-READ'; // 设置事务的隔离级别

SELECT @@TX_ISOLATION; // 查询事务的隔离级别

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下酒番陪绅士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值