Redis|在Spring事务管理下,Synchronized为啥还线程不安全?( 二 )
<1){ log.info("把录播的信息插入数据库失败 参数是->{}", JSON.toJSONString(courseChapterLiveRecord)); throw new RRException("把录播的信息插入数据库失败"); }}其实也就是说把事务包裹在Synchronized 里面
先自我批评一下在技术的道路上真的不要自己觉得是什么就是什么 上面的代码是错误的 其实我并没有测试过 就贴到文章上了 这是一个大忌 为什么很多技术文章有问题 因为很多就像我上面的一样 所以敦促自己以后做事情还是要扎扎实实
感谢 紫雨飞星 读者提出我的错误 具体错误的原因是因为调用savRecord方法的时候使用的是this对象 , 其实是没有被AOP处理的 , 也就是这个Transactional不会生效~~~
修改后的代码 自己注入自己
@Override public synchronized void saveCourseChapterLiveRecord(CourseChapterLiveRecord courseChapterLiveRecord) { courseChapterLiveRecordServiceImpl.saveRecord(courseChapterLiveRecord); } @Transactional public void saveRecord(CourseChapterLiveRecord courseChapterLiveRecord) { //先查数据看是否已经存了 if (findOrder(courseChapterLiveRecord)){ return;} int row = this.insertSelective(courseChapterLiveRecord); if (row<1){ log.info("把录播的信息插入数据库失败 参数是->{}", JSON.toJSONString(courseChapterLiveRecord)); throw new RRException("把录播的信息插入数据库失败"); }}利用中午的时间测了几次 确实是不会出现线程安全问题了
方案3 用redis 分布式锁 也是可以的 就算是多个副本也是能保证线程安全 。 这个后面的文章会有写到
结论在多线程环境下 , 就可能会出现:方法执行完了(synchronized代码块执行完了) , 事务还没提交 , 别的线程可以进入被synchronized修饰的方法 , 再读取的时候 , 读到的是还没提交事务的数据 , 这个数据不是最新的 , 所以就出现了这个问题 。
【Redis|在Spring事务管理下,Synchronized为啥还线程不安全?】Synchronized 失效关键原因:是因为Synchronized锁定的是当前调用方法对象,而Spring AOP 处理事务会进行生成一个代理对象 , 并在代理对象执行方法前的事务开启 , 方法执行完的事务提交 , 所以说 , 事务的开启和提交并不是在 Synchronized 锁定的范围内 。 出现同步锁失效的原因是:当A(线程) 执行完insertSelective()方法 , 会进行释放同步锁 , 去做提交事务 , 但在A(线程)还没有提交完事务之前 , B(线程)进行执行findOrder() 方法 , 执行完毕之后和A(线程)一起提交事务, 这时候就会出现线程安全问题 。
- 麒麟|荣耀新款,麒麟810+4800万超清像素,你还在犹豫什么呢?
- 智能手机市场|华为再拿第一!27%的份额领跑全行业,苹果8%排在第四名!
- 行业|现在行业内客服托管费用是怎么算的
- 零部件|马瑞利发力电动产品,全球第七大零部件供应商在转型
- 通气会|12月4~6日,2020中国信息通信大会将在成都举行
- 俄罗斯手机市场|被三星、小米击败,华为手机在俄罗斯排名跌至第三!
- 体验|闭上眼睛点外卖是什么感觉?时隔一年再次体验,进步令人欣慰
- 当初|这是我的第一部华为手机,当初花6799元买的,现在“一文不值”?
- 出海|出海日报丨短视频生产服务商小影科技完成近4亿元 C 轮融资;华为成为俄罗斯在线出售智能手机的第一品牌
- 看过明年的iPhone之后,现在下手的都哭了