Java Web基础的查漏补缺——事务的安全隐患
发布日期:2021-06-30 18:04:32 浏览次数:2 分类:技术文章

本文共 1073 字,大约阅读时间需要 3 分钟。

如果事务不考虑隔离性,那么就会引发读和写的问题。读的问题,我已在这篇文章中详细介绍过了。本文只关注写的问题。

写的问题:丢失更新

写的问题,这里指的是丢失更新。即指一个事务去修改数据库,另一个事务也修改数据库,最后的那个事务,不管是提交还是回滚都会造成前面一个事务的数据更新丢失。

在这里插入图片描述
解决丢失更新,通常有两种方法:悲观锁和乐观锁。

悲观锁

指事务在一开始就认为丢失更新一定会发生,这是一件很悲观的事情。说得更直白一点,悲观锁认为丢失更新一定会出现,还没有开始做,就已经认为一定会有丢失更新了。具体操作步骤如下:

  1. 所有事务在执行操作前,先查询一次数据,查询语句如下:

    select * from account for update;---(for update其实是数据库里面的锁机制,即一种排他锁)
  2. 哪个事务先执行这个语句,哪个事务就持有了这把锁,可以查询出来数据,后面的事务再执行这条语句,不会有任何数据显示,就只能等着;

  3. 一直等到前面的那个事务提交数据后,后面的事务数据才会出来,那么才可以往下接着操作。

这有点像男生去上卫生间似的,如果谁先来,谁就可以进去蹲着,后面来的人得等着。只有里面的人出来了,才能进去。这其实就是Java中同步的概念。为了更容易理解悲观锁,我画了下面一个图。

在这里插入图片描述

乐观锁

乐观锁是指从来不会觉得丢失更新会发生。那么它的具体做法是什么呢?其要求程序员在数据库中添加字段,然后在后续更新的时候,对该字段进行判定比对,如果一致才允许更新(即要求程序员自己手动控制)。例子如下:

  1. 数据库表中,额外添加了一个version字段,用于记录版本,默认从0开始,只要有针对表中数据进行修改的,那么version就+1;
  2. 开启A事务,然后开启B事务;
  3. A事务先执行数据库表操作。因为以前都没有人修改过,所以是允许A事务修改数据库的,但是修改完毕,就把version的值变成1了;
  4. B事务这时候如果想执行修改,那么是不允许修改的。因为B事务以前是没有查询过数据库内容的,所以它认为数据库版本还是0,但是数据库的版本经过A事务修改,已经是1了。所以这时候不允许修改,要求其重新查询;
  5. B事务重新查询后,将会得到version为1的数据,这份数据就是之前A事务修改过的数据,B在进行修改,也是在A的基础上修改的。所以就不会有丢失更新的情况出现了。

同样为了更容易理解乐观锁,我画了下面一个图。

在这里插入图片描述
乐观锁的机制,其实是通过比对版本或者比对字段的方式来实现的,这与大家在未来的学习中,或者在工作中,使用到的版本控制软件(SVN、GIT)机制是一样的。

转载地址:https://liayun.blog.csdn.net/article/details/94962046 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Java Web基础的查漏补缺——编写一个自己的数据库连接池
下一篇:入门Struts1第六讲——使用Struts1框架改造在线网上书店

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年05月01日 07时50分15秒