数据库第十三次作业 事务管理

简介: 数据库第十三次作业 事务管理

       事务处理机制在程序开发过程中有着非常重要的作用,它可以使整个系统更加安全,保证在同一个事务中的操作具有同步性


一、事务的概念

       现实生活中,人们经常会进行转账操作,转账可以分为两部分来完成,转入和转出,只有这两部分都完成才认为转账成功。在数据库中,这个过程是使用两条语句来完成的,如果其中任意一条语句出现异常没有执行,则会导致两个账户金额不同步,造成错误。


       为了防止上述情况的发生,MySQL中引入了事务,所谓事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一事务的操作具有同步的特点,如果其中一条语句无法执行,那么所有的语句都不会执行,也就是说,当事务中的语句,要么都执行,要么都不执行。


创建chapter06数据库:

e881189406e2441faaf033471a9a5804.png

进入chapter06数据库:

1a7d550c8f6e49cba8d1a2c00030ebc0.png

创建account表并插入相应的字段:

a74878a3907945c187e33e050c54cee9.png

给account表添加相应的数据:

dbcde7baf3ff4d17a5a3fe36b4e9e82d.png

查看account表

26ee7fb3f1934ddda9e4f9e5ed7824a4.png

开启事务,将a账户的100 元钱转给b账户,并提交事务:

a58acd3704744379a3d507e425ed2cdc.png

查看account表数据:

3feeb25895a842f9994c097585708456.png

二、事务的提交

开启一个事务,使用update语句实现又b账户向a账户转100元钱的功能

932c60a3428a40d3a6bf2bf1786fabef.png

查看account表:

a24d510ca07d4503aa07db8baa4b0312.png

退出数据库重新登录查询account表:

dadc29442d194d87b2f58fabe80e5780.png

81ef7165b87145ed9a24c086ea824a82.png

可以看出,转账操作并没有成功,因为没有提交事务就退出数据库了,由此可以得出事务中的语句不能自动提交。


下面为事务提交并且退出数据库,再登录查看,可以看出成功了

f439ff9d127b4fdb820119d7a6c81236.png

283070e64e904517b577eef70d321ef7.png

0ea1dcb2adbe4b4690ff2902cb2d9e4a.png

三、事务的回滚

开启一个事务,通过update语句将a账户的100元转给b账户,并查询结果:

874af0c498b84fe39f846f91cb5303fc.png

5197b3599a8a49fb830cf01c15c9cf44.png

a账户成功给b账户转账100元钱,此时a账户不能给b账户转账,由于事务还没有提交,就可以将事务回滚,如下是回滚后查询的结果:

82f19df452a44bb3a223914974ff58a8.png

四、事务的隔离级别

1、(read uncommitted)脏读

开启a,b两个账户(数据库)


设置b账户的隔离级别并查看

a1f29f09b8c5441d89acb5543ae8ffa7.png

f715b2df536942d7a422088b93c85a4b.png

为了证明脏读的情况,首先在b账户中开启一个事务,并在该事务中查询当前账户的余额信息:

075727a102604787b9401a7fb292ffee.png

在a账户中开启一个事务,并在当前窗口中执行转账功能,并查询b账户:

4f62fc2fe65b4b8489a2d001ab15545d.png

2e7a2eca29324cf3bae58329bc7c58bc.png

从查询结果可以看出,a账户已经成功给b账户转账100元钱,这是由于b账户的事务隔离级别较低,因此读取了a账户中还没提交的内容,出现脏读的情况。上述情况演示完,之后,还需将a账户的事务回滚,将b账户中的事务提交。

fae647a2759740f3a576b11279953369.png

1e8ccca4e1684df2b817618d16018f85.png

为了防止脏读现象的发生,需要将b账户的隔离级别设置为read commited(读提交),该级别可以避免脏读。

d3dadfd5b9824fb59711416a035ef3b4.png

为了说明没有出现脏读现象,首先b账户开启一个事务,并在该事务中查询各账户的余额信息:

42bf4030824c40a1b93538eb51784c0c.png

a账户重新开启一个事务,并实现转账功能:

c5733c9f5a7b413b8c9bc0629989db67.png

a账户转账成功后,可以在b账户中再次查询各账户的余额信息

3fbcf57d63a44f73856b1e652addf149.png

通过比对两次结果可以发现,b账户在同一事务中的查询结果是一致的,并没有查询到a账户中未提交的内容,因此可以说明read committed隔离级别可以避免脏读,最后分别将a账户的事务和b账户中的事务回滚。

7323ef199e914c7d949edd88c73c2827.png

c49c10bc402f4a518d4ad26ad9b546a4.png

2、(non-repeatable read)不可重复读

首先在b账户开启一个事务,然后在当前事务中查询各账户的余额信息,查询结果如下:

a30aba56ba79462cab9b1f4b50742cc5.png

在a账户中不用开启事务,直接使用update语句执行更新操作并查看即可:

e9d1effaa3244395a7227876978a1762.png

当a账户中的更新操作执行成功后,在b账户再次查询各账户的余额:

da6b2685f7494bf3bd010d0dc1fa6191.png

对比两次查询结果可以看出是不一致的,实际上这种操作是没错的,但是如果银行统计报表时,这种情况是不符合需求的,因为我们并不希望在一个事务中看到查询结果不一致,这就是不可重复读。上述情况演示成功后,还要将b账户的事务提交:

b689ef1c7eff47cabbd011b0245aa41d.png

为了防止重复读的情况出现,可以将该事务的隔离级别设置为repeatable read(可重复读):

9fac875648c44940af7bf2e1557f72c8.png

在b账户中,重新开启一个事务,然后使用select语句查询当前账户的余额:

ee085cae750447fe811525f0e3f32533.png

在a账户中不开启事务,直接使用update语句执行更新操作,并查询:

b6851a4febf147efa6eb17c165709459.png

当a账户的语句执行成功后,b账户在当前事务中,再次查询各账户的余额信息:

a7e3a573526843249e359331654c0a68.png

对比b账户两次查询结果可以发现,查询结果是一致的,并没有出现不同的数据,因此,可以说明事务的隔离级别为repeatable read时,可以避免重复读的情况。演示完成后,将b账户的事务提交:

b689ef1c7eff47cabbd011b0245aa41d.png

3、(phantom read)幻读

将b账户的隔离级别设置更低,设置为read committed:

1f0ffb06ee4642cda47e8674c5115b22.png

首先在b账户中开启一个事务,然后在当前事务中查询账户的余额信息:

3d1486ecd378420aaeb8cc6e0ea6990e.png

在对a账户添加操作之前,使用select语句查看当前a账户中的信息,执行语句如下所示:

d0626a8090f74d19ae3061977ef6ff7a.png

接下来对a账户添加操作,a账户不开启事务,执行执行添加操作即可:

939cc7b0f4e4497c81955d0167835de6.png

当a账户执行成功后,可以在b账户中再次查询账户的余额信息:

599ead84cc034e2497534570efe07495.png

通过对比b账户设置的read committed隔离级别前后,发现第二次查询数据时比第一次查询多一条记录,这种情况并不是错误的,但可以不符合实际需求。需求注意的是,上述情况演示完成后,将b账户中的事务提交:

fc4b2fb16fc74b2aadd4ad3fb8abf1da.png

为了防止幻读,可以将b账户的隔离级别设置为repeatable read:

7ab1cdcba4734eb68a57c31d3798bf2c.png

为了验证是否出现幻读,在b账户中开启一个事务,并在该事务中查询当前账户的余额信息:

1ce187fb0e004fb9826137b401b85412.png

在对a账户添加操作之前,使用select语句查看当前a账户中的信息:

c0107e587c7941e6a3cf7419d988be9f.png

接下来对a账户添加操作,在a账户中不开启事务,直接执行添加操作:

7ab1d7a80a044c5488ad0a5594993fb4.png

当a账户添加操作成功后,再次查询当前b账户的余额信息:

9518339102c2426c90052f8330525161.png

对比b账户的两次查询结果可以看出,同一事务中两次查询结果一致,并没有出现重复读取的情况,因此可以说明当前事务的隔离级别可以避免幻读,最后需要使用commit语句提交当前事务并查询:

5e50d5d357c9408d9c4555b48a81d674.png

4、(serializable)可串行化

事务的最高隔离级别,它在每个读的数据行上加上锁,使之不能相互冲突,因此导致大量的超时现象:


首先将b账户的隔离级别设置为serializable:

c71f6cb306254a9c899ff390b20f7e7a.png

在b账户中开启事务,然后使用select语句查询各个账户的余额信息:

ce09cc6060cc4d3388d389e717e787f9.png

a账户开启一个事务,并在该事务中插入操作:

39f3d5f4fb674f37971f3c48c0fc267e.png

从上述执行结果可以看出,当b账户正在执行事务中查询余额信息时,a账户中的操作是不能立即执行的


b账户查询完余额信息后,立即提交当前事务:

dd5907e5d2144b4c97a4cc611d2af188.png

当b账户中的事务提交成功后,a账户中的添加操作才能执行成功,并输出如下语句:

f9846c50b4df45d9897cfc91f64884ad.png

从上述情况可以看出,如果一个事务使用serializable(可串行化)隔离级别时,在这个事务没有被提交之前,其他线程只能等到当前操作完成之后,才能进行操作,这样非常耗时,而且会影响数据库的性能,通常情况下是不会使用这种隔离级别的。

目录
相关文章
|
4月前
|
数据库
数据库第十一次作业 视图的应用
数据库第十一次作业 视图的应用
34 1
|
12天前
|
关系型数据库 API 数据库
Django中的数据库事务管理:确保数据一致性
【4月更文挑战第15天】Django框架提供强大的数据库事务管理,确保ACID属性,保证数据一致性和完整性。文章深入讨论了Django事务管理,包括使用`@transaction.atomic`装饰器和`transaction.atomic()`上下文管理器手动控制事务,以及低级API进行精细管理。注意避免长时间事务、选择合适隔离级别、正确处理异常及了解数据库特性。掌握这些技巧对构建可靠Web应用至关重要。
|
1月前
|
SQL NoSQL 数据库
深入浅出:微服务架构下的数据库事务管理
【2月更文挑战第12天】 在当今微服务架构日益流行的背景下,如何有效地管理跨服务的数据库事务成为了开发与维护中的一大挑战。本文旨在探讨微服务环境下数据库事务管理的关键技术和策略,包括但不限于分布式事务的基本概念、常见的解决方案(如两阶段提交、补偿事务等),以及这些方案在实际应用中的优缺点比较。通过深入浅出的方式,本文希望能够帮助读者更好地理解并应对微服务架构下的数据库事务管理问题,进而提升系统的稳定性和可靠性。
|
4月前
|
SQL 关系型数据库 MySQL
数据库第十四次作业 电子商城项目
数据库第十四次作业 电子商城项目
24 0
|
4月前
|
存储 SQL 数据库
数据库第十二次作业 存储过程(PL/SQL语句集)的应用
数据库第十二次作业 存储过程(PL/SQL语句集)的应用
31 0
|
4月前
|
数据库
数据库第十次作业 视图
数据库第十次作业 视图
28 0
|
4月前
|
存储 关系型数据库 MySQL
数据库第八次作业 复习作业(工厂项目)
数据库第八次作业 复习作业(工厂项目)
51 0
|
4月前
|
数据库
数据库第七次作业 更新数据
数据库第七次作业 更新数据
26 0
|
4月前
|
Shell 数据库
数据库第六次作业 查询数据-多条件
数据库第六次作业 查询数据-多条件
37 0
|
4月前
|
数据库
数据库第五次作业 查询数据
数据库第五次作业 查询数据
32 0

热门文章

最新文章