当前位置: 首页 > news >正文

大兴安岭商城网站开发设计信用宁波企业网查询

大兴安岭商城网站开发设计,信用宁波企业网查询,济南建设银行网点,游戏网站模板源码需求场景 在项目的接口请求中#xff0c;我们有一个接口A需要事务支持#xff0c;在接口A中调用了方法B#xff0c;方法B也需要事务支持#xff0c;两者都带有Transactional注解。在B方法中是这个一个逻辑#xff0c;查询本地数据库是否包含属性值为一个特定值的字段… 需求场景 在项目的接口请求中我们有一个接口A需要事务支持在接口A中调用了方法B方法B也需要事务支持两者都带有Transactional注解。在B方法中是这个一个逻辑查询本地数据库是否包含属性值为一个特定值的字段如果没有的话就插入如果有的话就跳过。 问题难点及方案分析 首先最简单的方式是在数据层面加入唯一性约束但是项目中会出现报错并且这里我们要求不能在数据库层面进行操作数据的事务的隔离级别必须是可重复读只能在代码中保证数据插入的数据的唯一性。 PostMapping(/add) Transactional public String addUser(RequestBody User user) {//逻辑代码1...//逻辑代码1...//逻辑代码1...//插入逻辑boolean andInsertUser userService.getAndInsertUser(user);//逻辑代码2...//逻辑代码2...//逻辑代码2...return andInsertUser ? 添加成功 : 插入失败; }Transactionalpublic boolean getAndInsertUser(User user) {LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapperUser().eq(User::getAge, user.getAge());ListUser list list(lambdaQueryWrapper);if (Objects.nonNull(list) !list.isEmpty()) {return true;}return save(user);}难点1及方案分析 在并发的情况下可能两次请求查询基本同时执行都查询到了相同的结果发现没有数据然后都执行了插入的请求导致数据的重复。 针对于上述情况我们可以使用信号量机制来解决使用信号量之后即使在并发的情况下发生也只有一个线程能够真正执行里面的内容并且其他的线程获取资源失败之后并不会阻塞。 Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService {Semaphore semaphore new Semaphore(1);Transactionalpublic boolean getAndInsertUser(User user) {if (semaphore.tryAcquire()){try {LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapperUser().eq(User::getAge, user.getAge());ListUser list list(lambdaQueryWrapper);if (Objects.nonNull(list) !list.isEmpty()) {return true;}return save(user);} finally {semaphore.release();}}return true;} }难点2及方案分析 由于可重读读颗粒级别下存在存在幻读问题我们考虑这样一种情况两个请求a和b都进入了addUser方法其中a执行在逻辑代码1的时候b已经执行完成了插入逻辑当a执行到插入逻辑的时候semaphore.tryAcquire()一定是可以成功执行的而由于addUser方法添加了事务注解这就导致即使b线程已经执行完了插入逻辑但是a在执行插入逻辑的时候下面的代码在if判断的时候依然查不到刚才b插入的数据这里是因为a的事务开启是在b插入数据之前导致a查询的是a开启事务时候的快照快照中并不存在b刚才插入的数据这就导致了再次插入数据。 LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapperUser().eq(User::getAge, user.getAge());ListUser list list(lambdaQueryWrapper);if (Objects.nonNull(list) !list.isEmpty()) {return true;}return save(user);针对上述的情况原因就是a事务的开启在b事务提交之前。如果我们两条事务不是并发执行的而是一条事务执行完成之后另一个事务才开启就不会存在这个问题。 一个看似合理的解决方案 private volatile AtomicInteger stamp new AtomicInteger(0);PostMapping(/add) Transactional public String addUser(RequestBody User user) {int stamp_temp stamp.get();//逻辑代码1...//逻辑代码1...//逻辑代码1...//插入逻辑boolean andInsertUser userService.getAndInsertUser(user, stamp_temp, stamp);//逻辑代码2...//逻辑代码2...//逻辑代码2...return andInsertUser ? 添加成功 : 插入失败; }private static final Semaphore semaphore new Semaphore(1);Transactionalpublic boolean getAndInsertUser(User user, int stamp, AtomicInteger atomicInteger) {if (semaphore.tryAcquire()){if (Objects.equals(atomicInteger.get(), stamp)) {try {LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapperUser().eq(User::getAge, user.getAge());ListUser list list(lambdaQueryWrapper);if (Objects.nonNull(list) !list.isEmpty()) {return true;}return save(user);} finally {atomicInteger.incrementAndGet();semaphore.release();}}}return true;} }这里采用了类似于解决ABA问题的解决方案但是会存在这样一种情况假如两个线程a和b都执行了addUser()方法假如起始时候stamp的值是0a线程执行到了逻辑代码2这个时候stamp一定已经被a线程变成了1此时线程b这个时候首先获取stamp的值是1线程a还没有执行完成也就是事务还没有提交后面执行插入逻辑的时候当然一样会存在读取不到最新数据的问题导致b线程还是能够插入成功。最后两个事务都会提交成功这样还是会插入两次相同的数据。 使用select for update保证当前读 这个方法在MySQL中没有进行实验在postgresql中读已提交和可重复读隔离界别下均读取不到其他事务已经插入但是没有提交的数据。仍然无法解决问题。 难点3及解决分析 以上的解决方案都是在单机环境下的解决方案多机分布式环境下仍然会存在很多的问题。针对于以上问题提出一下两种方案 使用消息中间件将消息发到mq中进行消费这样就不会和业务前面的业务逻辑代码冗余在一起提高接口响应速度。但是由于消息消费可能出现并发消费的问题导致同时插入多条相同数据。使用redis分布式锁来解决消息并发消费的问题保证分布式环境下消费消息的同步性。同时可以根据业务逻辑丢弃消息。
http://www.zqtcl.cn/news/389841/

相关文章:

  • 做地推的网站做网站感觉挣不到钱啊
  • 网站建设公司哪家好 搜搜磐石网络营销网站建设免费
  • 如何改网站的内容源码买卖网站
  • 企业网站 报价免费创意字体设计
  • 调用百度地图做全景的网站网站维护要求
  • 济宁网上做科目一的网站网站维护工程师薪酬
  • 领先的响应式网站建设平台湖北企业建站系统信息
  • 嘉兴市住房和城乡建设局网站巩义网站建设方案报价
  • 桂林做网站的公司哪家最好长沙网络工程学院
  • 广州 天河网站设计wordpress评论开关
  • 河南郑州建设网站做贺卡网站
  • 我的家乡湛江网站设计烟台网站建设招聘
  • 如何做网站改版评析网站建设报价单
  • 有关天猫网站开发的论文热狗seo顾问
  • 西安成品网站建设云主机建网站教程
  • 网站后台是怎么更新电商网站开发需求文档
  • 教人怎么做网页的网站有关建设网站的问题
  • wordpress资源站源码网站规划与建设课设报告
  • 网站后台ftp账户企企业业网网站站建建设设
  • 网站建设公司专业的建站优化公司成都天府新区网站建设
  • 建站模板 discuzui设计的流程有哪些步骤
  • 网站建设 军报汕头网站建设网站
  • 便宜购物网站大全网站建设简介联系方式
  • 网站没有后台登陆文件夹公司怎么建立网站吗
  • 营销网站建设流程图网站开发目前主要用什么技术
  • 网站建设与管理维护 李建青大连网站设计费用
  • 网站建设制作心得团队盐都区城乡建设局网站
  • 网页设计公司网站设计结婚网站模版
  • 做文字图网站设计师网站资源
  • 建筑材料采购网站做早餐烧菜有什么网站