数据库事务

一.事务概念:

  • 所谓数据库事务,是指作为单个逻辑工作单元执行的一系列操作要么都执行,要么都不执行,简单的说,事务就是一堆SQL语句的执行绑定在一起,要么都执行成功,要么都执行失败,即都执行成功才算成功,否则就会恢复到这堆SQL语句执行前的状态
  • 我们以银行转账为例:张三给李四转了100元

1)给张三账户上减去100

update 帐户表 set money=money-100 where name='张三';

2)给李四账户上添加100元

update 账户表 set money=money+100 where name='李四';

如果说第一条语句执行成功了,而执行第二条语句之前由于程序中断,抛出了一个异常导致第二条语句没有执行成功,那么李四账户上没有添加成功,那么张三账户上也不可能减少100,这样也就更好的理解了事务

二.事务的四大特征

事务有四大特性是:
1)原子性:事务中所有的操作是不可在分的原子单位,事务中所有的操作要么都执行成功,要么都执行失败
2)一致性:事务执行前后,数据库状态应保持一致,如转账业务,无论事务执行成功与否,参与转账的两个账号金额之和应保持一致
3)隔离性:两个事务的操作是完全隔离的,双方是看不到彼此的中间执行状态,两者互不干扰,也就是说,在事务中查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改之后的状态,事务不会查看到中间状态的数据,如:在A事务中,查看另一B事务(正在修改张三的账户金额)中张三的账户金额,要么查看到B事务之前的张三的账户金额,要么查看到B事务之后张三的账户金额。
4)持久性:一旦事务提交成功后,事务中所有的数据操作都必须持久的保存数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据

三.事务并发读问题

所谓事务并发,就是多个事务对相同数据同时进行操作
在事务并发时,如果没有采取必要的隔离措施,可能会导致各种并发问题,破坏数据的完整性,这些问题中,其中三类是读问题,分别是:脏读,不可重复读,幻读
我们分别详解三类读问题:

  • 脏读:一个事务中读到另一个事务未提交的数据
    例如:A给B转账100元但未提交事务,在B查询之后,A做了回滚操作,那么B查询到A未提交的数据
-- 在窗口1中,开启事务,执行A给B转账100元
set tx_isolation='read-uncommitted'; -- 允许脏读、不可重复读、幻读
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
update acc set money=money-100 where name='A';
update acc set money=money+100 where name='B';

-- 在窗口2中,开启事务,查询B的账户金额
set tx_isolation='read-uncommitted'; -- 允许脏读、不可重复读、幻读
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
select * from acc where name= 'B'; -- 出现脏数据

-- 切换到窗口1,回滚事务,撤销转账操作。
rollback; -- 回滚事务

-- 切换到窗口2,查询B的账户金额
select * from acc where name='B';

在窗口2中,B看到自己的账户增加了100元(此时的数据A操作事务并未提交),此种情况称为“脏读”

  • 不可重复读:对同一记录的两次读取不一致,因为另一事务对该记录做了修改,在一个事务中读到另一个事务已经提交的数据
    例如:在事务1中,前后两次查询A账户的金额,在两次查询之间,另一事务2对A账户的金额做了修改,此种情况下可能会导致事务1中,前后两次查询结果不一致
-- 在窗口1中,开启事务,查询A账户的金额
set tx_isolation='read-uncommitted'; -- 允许脏读、不可重复读、幻读
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
select * from acc where name='A';

-- 在窗口2中,开启事务,查询A的账户金额减100
set tx_isolation='read-uncommitted'; -- 允许脏读、不可重复读、幻读
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
update acc set money=money-100 where name='A'; -- A账户减去100
select * from acc where name='A';
commit; -- 提交事务

-- 切换到窗口1,再次查询A账户的金额。
select * from acc where name='A'; -- 前后查询结果不一致

在窗口1中,前后两次对同一数据(账户A的金额)查询结果不一致,是因为在两次查询之间,另一事务对该A账户的金额做了修改

  • 幻读:对同一张表的两次查询不一致,是因为另一事务插入了一条记录(针对插入或删除操作)
-- 在窗口1中,开启事务,查询账户表中是否存在id=3的账户
set tx_isolation='read-uncommitted'; -- 允许脏读、不可重复读、幻读
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
select * from acc where id=3;

-- 在窗口2中,开启事务,往账户表中插入了一条id为3记录,并提交事务。
-- 设置mysql允许出现脏读、不可重复度、幻读
set tx_isolation='read-uncommitted';
use jt_db; -- 选择jt_db库
start transaction; -- 开启事务
insert into acc values(3, 'C', 1000);
commit; -- 提交事务

-- 切换到窗口1,由于上面窗口1中查询到没有id为3的记录,所以可以插入id为3的记录。
insert into acc values(3, 'C', 1000); -- 插入会失败!

在窗口1中,查询了不存在id为3的记录,所以接下来要执行插入id为3的记录,但是还未执行插入时,另一事务中插入了id为3的记录并提交了事务,所以接下来窗口1中执行插入操作会失败。
探究原因,发现账户表中又有了id为3的记录(感觉像是出现了幻觉)。这种情况称之为"幻读

四.事务隔离级别

针对以上所说的并发事务的读问题,事务设置了隔离级别,在相同环境下,对数据执行相同的操作,设置不同的隔离级别,可能会导致不同的结果,不同事务隔离级别能够解决的数据并发问题的能力也是不同的

  • RED UNCOMMITTED(读未提交数据)
    该级别是安全级别最低,可能出现任何事务并发问题(比如:脏读,不可重复读,幻读),但是性能最好
set tx_isolation='read-uncommitted';
  • RED COMMITTED(读已提交数据)
    该级别是为了防止脏读,没有处理不可重复读,也没有处理幻读
set tx_isolation='read-committed';
  • REPEATABLE RED(不可重复读)
    该级别是防止脏读和不可重复读,不能处理幻读
set tx_isolation='repeatable-read';在这里插入代码片
  • SERIALIZABLE(串行化)
    不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的,性能最差,但是安全性最高
set tx_isolation='serialiable';
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值