数据库之事务详解

一、事务的概念

1、数据库事务

  数据库事务通常指对数据库进行读或写的一个操作序列。它的存在包含有以下两个目的:

  • 为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。

  • 多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

2、系统事务

  处理一系列业务处理的执行逻辑单元,该单元里的一系列类操作要不全部成功要不全部失败

二、事务的属性(ACID)

1、原子性(Atomicity)

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

【例子】:
  A向B转账100元,需要执行两个操作:A账户减少100元,B账户增加100元。这两个操作要么都同时执行成功,要么都执行失败,否则一个成功,一个失败都是不合理的。

2、一致性(Consistency)

  数据库从一个一致性状态变到另一个一致性状态 (经过一系列操作后,所有的操作和更新全部提交成功,数据库只包含全部成功后的数据就是数据的一致性)。

【例子】:
  A向B转账100元,假设转账之前这两个用户的钱加起来总共是2000,那么A向B转账之后,不管这两个账户怎么转,A用户的钱和B用户的钱加起来的总额还是2000,这个就是事务的一致性。

3、隔离性(Isolation)

  多个事务,事务的隔离性是指多个用户并发访问数据库时, 一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

4、持久性(Durability)

  持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

三、数据库事务并发存在的问题

  如果我们在不考虑隔离性问题时,事务是存在三种并发访问问题的:

1、脏读

  A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。
在这里插入图片描述
  在这个例子中,A事务修改了用户名,但是回滚了,这时候B事务读数据时出现了脏读。

2、不可重复读

  不可重复读是指A事务读取了B事务已经提交的更改数据(针对的是update或delete)。然后事务A在前后两次很短的时间内读取数据的时候,发现数据不匹配了。
在这里插入图片描述
在这里插入图片描述
  在这个例子中,A事务修改了用户名并提交了,这时候B事务两次读数据时出现了不一致的现象。

3、幻读

  A事务读取B事务提交的新增数据,会引发幻读问题(针对的是insert)。即事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。
在这里插入图片描述
  在这个例子中,A事务首先读取数据,这时候B事务增加了一条数据,然后A事务再次修改数据时发现多了一条数据(像是产生了幻觉)。

四、事务的隔离级别

1、read uncommitted(读未提交的数据)

  事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读”。

2、read committed(读已提交的数据)

  大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读”,但不能避免“幻读”和“不可重复读”。该级别适用于大多数系统。

3、repeatable read(重复读-MySQL默认隔离级别)

  保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读”和“不可重复读”的情况,但不能避免“幻读”,但是带来了更多的性能损失。

4、serializable(串行化)

  最严格的级别,事务串行执行,资源消耗最大。

在这里插入图片描述

五、事务的SQL相关操作

/**** 1、事务的创建 ****/

// 禁止自动提交功能(只针对当前事务)
SET autocommit=0;
// 开启事务
START TRANSACTION;
// 事务处理(只能是增删改查语句:select,update,insert,delete)
UPDATE t_account SET balance=balance-500 WHERE username="Eric";
UPDATE t_account SET balance=balance+500 WHERE username="Lx";
// 结束事务
COMMIT;

/**** 2、事务的并发和隔离级别 ****/

// 查看默认的隔离级别(可重复读)
SELECT @@tx_isolation;

// 修改隔离级别(未提交读-允许脏读)
set session transaction isolation level read uncommitted;

// 事务1
SET autocommit=0;
START TRANSACTION;
UPDATE t_account SET username="eric" WHERE id=1;
COMMIT;

// 事务2
SET autocommit=0;
START TRANSACTION;
SELECT * from t_account;
COMMIT;

// 修改隔离级别(已提交读-不允许脏读但允许可重复读)
set session transaction isolation level read committed;

// 修改隔离级别(重复读-不允许脏读、重复读但允许幻读,这是MySQL默认隔离级别)
set session transaction isolation level repeatable read;

// 修改隔离级别(串行化-不允许脏读、重复读、幻读,但性能十分低下)
set session transaction isolation level serializable;

/**** 3、保存回滚点 ****/

SET autocommit=0;
START TRANSACTION;
DELETE FROM t_account WHERE id=2; // 数据被删除
SAVEPOINT a; // 设置回滚点
DELETE FROM t_account WHERE id=3; // 这里的数据不会被删除
ROLLBACK TO a; // 回到回滚点

六、事务总结

  事务是指一系列将要发生的连续的操作。事务安全是为了保证一系列操作的结果保持同步,保证数据的完整性。开启事务后,操作的结果会先保存到事务日志中,等操作完成提交事务后,才会修改表中的数据。

【Note】:
  只有innodb存储引擎和bdb存储引擎才支持事务安全。

参考:https://blog.csdn.net/love_legain/article/details/54706272
https://blog.csdn.net/z646721826/article/details/79412459
https://blog.csdn.net/starlh35/article/details/76445267
https://www.cnblogs.com/fengdejiyixx/p/7988935.html
https://blog.csdn.net/Somhu/article/details/78775198

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

~青萍之末~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值