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

创建并使用chapter06数据库:

 

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

给account表的字段添加相应的数据:

查看account表中的数据

 

 开启事务,将a账户的100 元钱转给b账户,并提交事务,查看表中money的数据:

 开启一个事务,使用update语句实现又b账户向a账户转100元钱的功能,并查看account表中的数

据:

 退出MySQL,重新查看account表中数据:

 

从上述结果可以看出,转账操作并没有成功,因为没有提交事务就退出数据库了,由此可以得出事务中的语句不能自动提交,因此当前的操作就自动取消了。再执行上述语句,使用commit语句提交事务:

下面为事务提交并且退出数据库,再登录查看,使用select语句查询数据库中账户的余额:

 

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

 

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

 

(read uncommitted)脏读

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

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

 

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

 

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

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

 

 

为了防止脏读现象的发生,需要将b账户的隔离级别设置为read commited(读提交),该级别可以避免脏读。为了说明没有出现脏读现象,首先b账户开启一个事务,并在该事务中查询各账户的余额信息:

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

 

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

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

 

                                         (non-repeatable read)不可重复读

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

 

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

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

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

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

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

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

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

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

                                   (phantom read)幻读

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

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

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

 

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

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

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

 

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

 

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

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

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

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

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

 

                           (serializable)可串行化

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

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

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

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

 

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

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

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

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值