工作日志-7-30-2018-畅游

本文分享了一位新手开发者在实现手机验证码发送及CDK发放活动中遇到的并发问题,并详细讨论了如何利用数据库锁和事务来解决这些问题,确保数据的一致性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

入职快一周,正在熟悉整个开发环境,想尽快的跟上前辈们。
    部门是做游戏活动的,项目框架主要是spring,持久层框架没有用mybtis,用的是spring 的jdbc;
    上周五的时候想要独自实现一个简单的手机验证码发送和CDK发放的活动(游戏名叫星际战甲),因为入职后就一直在看前辈们的代码,已经从头到尾看过了两个另外的活动。
    总共三天做完,期间踩的坑主要是在数据库和开发工具。Oracle Idea。
    今天周一,上午把活动跑起来了,几个异常处理也没问题。但是跟老大汇报完工作,发现疏漏了一个很严重的问题,并发情况下数据库的读写问题。

    问题1.CDK发送问题(老大提醒的):高并发情况下,上一个请求已经将某个CDK获取,但是还没有修改成已发送状态,马上又被另一个请求线程获取到,结果就是两个账号获得了同一个CDK。
    问题2.恶意请求攻击下,用户获得多个CDK:同一个用户发起了获取CDK的请求,请求线程来不及修改为此用户已获取CDK状态,又一个请求过来(还是这用户的),结果就是同一个账号获得了多个CDK.
    问题3.同一用户发起大量的获取验证码请求:因为短信发送需要成功,所以这个api调用需要次数限制。
    问题4.db各个表记录的状态'不一致':因为db操作是不能肯定是成功的,结果表现为:获取验证码请求执行期间,获取到了CDK,CDK也有效,也修改成已发送状态,但是想要修改用户为已获取CDK状态失败,那么这CDK就浪费掉了。

 

问题1 2 总的来说,db锁解决
问题3 可以用ip访问次数限制 或者账号发送验证码次数限制解决
问题4 把获取CDK, 修改用户、 CDK状态信息,集成到一个事务中进行,根据事务的特性(要么全部成功,要么都不成功回滚)解决掉

1 .db锁

 数据库锁按粒度大小分为 表级锁 行级锁 (常见DBMS都支持) 还有页级锁(Mysql支持)

     按照策略    乐观锁 悲观锁
     从读写角度,分共享锁(S锁,Shared Lock)和排他锁(X锁,Exclusive Lock),也叫读锁(Read Lock)和写锁(Write Lock)。        

          理解 :当一个事务(DB Connection)对某一数据进行读取,加上S锁,接着另一个事务也想要读取这个数据,这是可以的。但是修改就不行。(大家都可以读,在有人读的时候是不可以修改的)
                当一个事务对某一数据进行读/写操作加上X锁,接着另一个事务想要读 /写 都不可以 (一个数据(一个厕所)排队使,在对同一数据(数量不限)上实现事务序列化执行)

          使用方法: for update (作用是用于对选择的行加排他锁的) ,with(rowlock,xlock,tablock,paglock)(mysql 可使用)

2.事务

public void getGiftRequestProcess(Map<String,String> result ,String phone,String identifyCode){
        try{          liveRequireDao.getJdbcTemplate().getDataSource().getConnection().setAutoCommit(false);
            //1.根据活动登记表是否存在该手机号
            boolean isEixtLoginByPhone=isExitPhone(phone); //Rlock Xlock 对这个phone这条记录加行级排它锁 //防止同一个用户同时多次的获取礼包请求
            if (isEixtLoginByPhone){
                //2.判断是否已经获得过礼包
                boolean isAuth=isAuth(phone);
                if (!isAuth){
                    //3.匹配验证码
                    boolean isIdentifyCodeRight=isIdentifyCodeRight(phone,identifyCode);
                    if (isIdentifyCodeRight){
                        //4.从db中获取一个新的cdk
                        CdkBean cdkOfNew=getCdkForNew(); //Rlock Xlock对这个cdk记录加行级排它锁 防止被其他请求对应的线程给获取到
                        //5.判断是否获取到有效的Cdk
                        boolean isCdkLeagal=isCdkLegal(cdkOfNew);
                        if (isCdkLeagal){
                            //6.修改这个cdk的信息 从可获得 -> 已领取
                            int dbOpreOfUpdateCdk=updateCDKToSended(cdkOfNew.getId());
                            if (dbOpreOfUpdateCdk>0){
                                //7.修改用户登录信息置为已获取cdk
                                int dbOpreOfUpdateAuth=updateLoginToGetCdk(phone,cdkOfNew.getCdkValue());
                                if (dbOpreOfUpdateAuth>0){
                                    //成功获取cdk 响应前端
                                    

	

失败,因为jdbcTemplate的Connection 是从dataSource.getConnection()来的,而dataSource又是连接池实现,故jdbcTemplate的每次curd都不能确定是同一个Connection对象。事务寄托在Connection对象实现。
    解决办法,@Transaction
    Spring的Aop事务管理底层实现时,如果当前线程存在connection,说明当前业务需要事务,那么就将当前线程中的connection返回回去,否则就从连接池中获取connection并返回回去;保证同一个connection对象。

标题Python网络课程在线学习平台研究AI更换标题第1章引言介绍Python网络课程在线学习平台的研究背景、意义、国内外现状和研究方法。1.1研究背景与意义阐述Python在线学习平台的重要性和研究意义。1.2国内外研究现状概述国内外Python在线学习平台的发展现状。1.3研究方法与论文结构介绍本文的研究方法和整体论文结构。第2章相关理论总结在线学习平台及Python教育的相关理论。2.1在线学习平台概述介绍在线学习平台的基本概念、特点和发展趋势。2.2Python教育理论阐述Python语言教学的理论和方法。2.3技术支持理论讨论构建在线学习平台所需的技术支持理论。第3章Python网络课程在线学习平台设计详细介绍Python网络课程在线学习平台的设计方案。3.1平台功能设计阐述平台的核心功能,如课程管理、用户管理、学习跟踪等。3.2平台架构设计给出平台的整体架构,包括前后端设计、数据库设计等。3.3平台界面设计介绍平台的用户界面设计,强调用户体验和易用性。第4章平台实现与测试详细阐述Python网络课程在线学习平台的实现过程和测试方法。4.1平台实现介绍平台的开发环境、技术栈和实现细节。4.2平台测试对平台进行功能测试、性能测试和安全测试,确保平台稳定可靠。第5章平台应用与效果分析分析Python网络课程在线学习平台在实际应用中的效果。5.1平台应用案例介绍平台在实际教学或培训中的应用案例。5.2效果评估与分析通过数据分析和用户反馈,评估平台的应用效果。第6章结论与展望总结Python网络课程在线学习平台的研究成果,并展望未来发展方向。6.1研究结论概括本文关于Python在线学习平台的研究结论。6.2研究展望提出未来Python在线学习平台的研究方向和发展建议。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值