首页 > 数据库 >MYSQL悲观锁-用户余额

MYSQL悲观锁-用户余额

时间:2023-02-20 11:58:08浏览次数:59  
标签:info log Thread person 余额 悲观 MYSQL id aud

无论什么锁JAVA的synchronized也好,还是MYSQL的锁都好,要注意分布式环境与单机环境

1.乐观锁

乐观认为并发不高,甚至没有并发。其中一种实现方式依靠在表中多加一个版本号字段,每次查询更新就按这个版本号,假设在修改时版本号与数据库不一致,就需要尝试重连(重新执行)。

查询

SELECT * FROM user WHERE id = #{id}

修改

UPDATE user SET .... WHERE id = #{id} AND version = #{version}

缺点:当出现并发时,可能会一直尝试重连

2.悲观锁

悲观认为并发经常出现,比如用户的余额问题。需要注意在Spring-Boot中悲观锁需要再事务逻辑中才会生效。悲观锁分为两种

悲观锁锁类 = 查询字段为索引 ? 行级锁 : 表级锁

实现方式

Mapper(核心为末尾的FOR UPDATE关键词)

@Select("SELECT * FROM person WHERE id = #{0} FOR UPDATE")
Person selectMoneyById(Integer id);

Service(核心为开头的事务)

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deductTicket(Integer aud, Integer ticket) 
        log.info("线程{}:start", Thread.currentThread().getName());
        Person person = baseMapper.selectMoneyById(aud);
        
        // 上面会阻塞,直到解锁(事务结束)
        log.info("线程{}:mid => {}", Thread.currentThread().getName(), person)
        
        if (person.getTicket() < ticket) {
            log.info("余额不足 => aud:{},targetTicket:{},nowTicket:{}", aud, ticket, person.getTicket());
            log.info("线程{}:end", Thread.currentThread().getName());
            return false;
        }
        
        // 加个延时看效果
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        baseMapper.updateById(person.setTicket(person.getTicket() - ticket));
        log.info("扣款成功 => aud:{},targetTicket:{},nowTicket:{}", aud, ticket, person.getTicket());
        log.info("线程{}:end", Thread.currentThread().getName());
        return true;
    }

--------------小马哥原创------------------

标签:info,log,Thread,person,余额,悲观,MYSQL,id,aud
From: https://www.cnblogs.com/KaiStudy/p/17136813.html

相关文章

  • Docker中Mysql容器忘记密码的处理方法
    今天非常的倒霉,因为学习了Vue的相关知识,想自己写一个后端服务器来练习一下Vue然后忘记了Docker中Mysql的密码。。。很抽象下面是我的解决方法一、如果在本地的Navica......
  • MySQL锁之深入死锁分析
    目录1死锁产生原因分析1.1产生原因1.2产生示例1.2.1案例一1.2.2案例二1.2.3案例三1.2.4案例四1.2.5案例五1.2.6案例六1.3死锁预防策略1.4剖析死锁的成因1.5解......
  • Mysql主从复制
    达到效果主数据库数据变更,从库对应同步变更(包含表、字段)前提条件两台数据库的数据要一致配置my.cnf主数据库配置#数据库服务器id,这个id用来在主从服务器中标记唯一......
  • 【Docker-3】Docker-Compose安装常用软件Nginx、Mysql、Redis、Java
    创建应用目录结构nginxconf.d-放置自定义的配置文件default.conflog-日志存储位置nginx.conf -nginx总配置文件docker-compose.ymlmysqlconf-放置自......
  • MYSQL重置密码
    以管理员身份打开命令行。停止MySQL服务(netstop服务名)。切换到MySQL的bin文件下,输入mysqld--console--skip-grant-tables--shared-memory。上个窗口保留不要关......
  • linux mysql
    mysql-uroot-p;mysql>createdatabaseghost;mysql>showdatabases;mysql>exitmysql>selectuser();//查看当前登录的用户mysql>showglobalvariableslik......
  • 小白之路--MySQL
    一、MySQL前言MySQL是学习阶段接触比较多的数据库,因为它开源免费,学习成本还是比较低的二、MYSQL安装MySQL安装教程,已经成功安装到电脑里面缺一个环境变量图,这找了......
  • mysql 如何查看表的大小
    mysql查看表的大小方法:1.查看所有数据库容量大小selecttable_schemaas'数据库',sum(table_rows)as'记录数',sum(truncate(data_length/1024/1024,2))as'数据......
  • mysql事务
    分为显示(有明显的开启和结束的标记)和隐示事务select@@autocommit:为0的时候为禁用setautocommit=0开启事务的方式starttransaction;————;......
  • centos7安装mysqlclient报错
    错误如图  解决办法#先安装mysql-devel,后安装mysqlclientyuminstallmysql-develpip3installmysqlclient ......