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

大型门户网站设计解决方案英语网站建设策划书

大型门户网站设计解决方案,英语网站建设策划书,企业注册网上申请入口,云主机建网站教程背景 对于一些内部使用的管理系统来说#xff0c;可能没有引入Redis#xff0c;又想基于现有的基础设施处理并发问题#xff0c;而数据库是每个应用都避不开的基础设施之一#xff0c;因此分享个我曾经维护过的一个系统中#xff0c;使用数据库表来实现事务锁的方式。 之…背景 对于一些内部使用的管理系统来说可能没有引入Redis又想基于现有的基础设施处理并发问题而数据库是每个应用都避不开的基础设施之一因此分享个我曾经维护过的一个系统中使用数据库表来实现事务锁的方式。 之前在文章Java业务功能并发问题处理中实现了使用MySQL行锁、Redis分布式锁来处理业务并发问题这次来填坑了如果想了解其他并发问题处理方式和区别可以看看文章Java业务功能并发问题处理哈。 业务流程说明 方案分析 适用场景 应用服务有多个实例但是数据库是单实例没有用上Redis的应用服务想通过现有的基础设施解决并发数据问题 待改进措施 设置超时机制当出现锁无法及时释放时需要手动删除表数据可以设置逻辑删除字段或者定时器删除过期数据重试获取锁机制设置一定的循环次数当获取不到锁时休眠200毫秒再次获取直到循环次数用尽后再返回失败锁重入支持通过增加加锁次数字段让当同一个线程可以重复获取锁 程序实现过程 框架及工具说明 技术框架SpringBoot、MyBatis、Maven数据库MySQL测试工具Apifox表设计及代码说明 唯一索引需要有一个用于判断唯一的字段在数据库表中通过指定唯一索引来实现加锁的线程号避免A线程加的锁被B线程删除锁的可见性要单独事务添加事务锁的逻辑应在我们执行业务逻辑的事务之前且不能跟业务逻辑的事务在一块否则在事务提交前其他线程根本看不到这个锁也就达不到我们锁的目的了为了我们的锁更方便使用也可以将加锁逻辑抽到注解中实现注解的实现流程 在pom文件中引入spring-boot-starter-aop编写自定义注解ConcurrencyLock实现切面类Aspect逻辑 代码展示 为了能让大家更关注加解锁逻辑本文只保留主要代码参考链接处会放置码云gitee的源码地址(或者点击此处跳转) 另外本文就不展示注解方式的使用了以免占用篇幅。 代码结构图 实体类 /*** 并发锁实体类*/ public class ConcurrencyLockBean {/*** 数据库主键*/private Long id;/*** 操作节点*/private String businessNode;/*** 订单唯一编号*/private String businessUniqueNo;/*** 线程ID*/private Long threadId;/*** 创建日期*/private Date creationDate; }/*** 订单实体类*/ Setter Getter ToString public class OrderInfoBean {/*** 自增长主键*/private int id;/*** 订单号*/private String orderNo;/*** 物料数量*/private Integer itemQty; }ConcurrencyLockServiceImpl.java Slf4j Service public class ConcurrencyLockServiceImpl implements ConcurrencyLockService {ConcurrencyLockMapper mapper;/*** service类注入*/AutowiredConcurrencyLockServiceImpl(ConcurrencyLockMapper mapper) {this.mapper mapper;}Overridepublic Boolean tryLock(String businessNode, String businessUniqueNo) {long threadId Thread.currentThread().getId();ConcurrencyLockBean concurrencyLock mapper.selectConcurrencyLock(businessNode, businessUniqueNo);if (concurrencyLock ! null) {log.info({}数据正在操作中请稍后, threadId);return false;}ConcurrencyLockBean lock new ConcurrencyLockBean();lock.setBusinessNode(businessNode);lock.setBusinessUniqueNo(businessUniqueNo);lock.setThreadId(threadId);try {int insertCount mapper.insertConcurrencyLock(lock);if (insertCount 0) {log.info({}获取锁失败请稍后重试, threadId);return false;}} catch (Exception e) {log.info({}获取锁异常请稍后重试, threadId);return false;}log.info({}完成锁表插入, threadId);return true;}Overridepublic void unLock(String businessNode, String businessUniqueNo) {ConcurrencyLockBean lock new ConcurrencyLockBean();long threadId Thread.currentThread().getId();lock.setThreadId(threadId);lock.setBusinessNode(businessNode);lock.setBusinessUniqueNo(businessUniqueNo);mapper.deleteConcurrencyLock(lock);log.info({}执行解锁完毕, threadId);} }ConcurrencyLockMapper.java import org.apache.ibatis.annotations.Param;public interface ConcurrencyLockMapper {/*** 根据业务节点和唯一业务号查询锁*/ConcurrencyLockBean selectConcurrencyLock(Param(businessNode) String businessNode, Param(businessUniqueNo) String businessUniqueNo);/*** 插入锁*/int insertConcurrencyLock(ConcurrencyLockBean lock);/*** 删除锁*/int deleteConcurrencyLock(ConcurrencyLockBean lock); }ConcurrencyLockMapper.xml ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.runningrookie.mapper.ConcurrencyLockMapperselect idselectConcurrencyLock resultTypecom.runningrookie.domain.ConcurrencyLockBeanSELECTTHREAD_ID,BUSINESS_NODE,BUSINESS_UNIQUE_NO,CREATION_DATEFROM concurrency_lockWHERE BUSINESS_UNIQUE_NO #{businessUniqueNo}AND BUSINESS_NODE #{businessNode}/selectinsert idinsertConcurrencyLock useGeneratedKeystrue keyPropertyidINSERT INTO concurrency_lock (THREAD_ID,BUSINESS_NODE,BUSINESS_UNIQUE_NO,CREATION_DATE)VALUES(#{threadId}, #{businessNode}, #{businessUniqueNo}, NOW());/insertdelete iddeleteConcurrencyLockDELETE FROM concurrency_lockWHERE THREAD_ID #{threadId}and BUSINESS_NODE #{businessNode}and BUSINESS_UNIQUE_NO #{businessUniqueNo}/delete /mapperConcurrencyLock.java注解 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented public interface ConcurrencyLock {String businessNode();String businessUniqueNoKey(); }ConcurrencyLockAspect.java注解类 Aspect Component Slf4j public class ConcurrencyLockAspect {ConcurrencyLockService concurrencyLockService;AutowiredConcurrencyLockAspect(ConcurrencyLockService concurrencyLockService) {this.concurrencyLockService concurrencyLockService;}// 环绕切面Around(annotation(concurrencyLock))public Object around(ProceedingJoinPoint joinPoint, ConcurrencyLock concurrencyLock) throws Throwable {long threadId Thread.currentThread().getId();Object[] args joinPoint.getArgs();if (args.length 0) {return joinPoint.proceed();}// 通过反射获取值String invokeMethodName get concurrencyLock.businessUniqueNoKey().substring(0, 1).toUpperCase() concurrencyLock.businessUniqueNoKey().substring(1);// 获取Order类的Class对象Class? clazz args[0].getClass();// 获取getOrderNo方法的Method对象Method method clazz.getMethod(invokeMethodName);// 调用getOrderNo方法并获取返回值String businessUniqueNo method.invoke(args[0]).toString();Boolean isSuccessLock concurrencyLockService.tryLock(concurrencyLock.businessNode(), businessUniqueNo);if (!isSuccessLock) {log.info({}加锁失败请稍后重试, threadId);// 生成与切点方法相同的返回对象return AjaxResult.error(加锁失败请稍后重试);}try {log.info({}开始执行业务逻辑, threadId);joinPoint.proceed();} finally {concurrencyLockService.unLock(concurrencyLock.businessNode(), businessUniqueNo);}return joinPoint.proceed();} } OrderInfoController.java RestController RequestMapping(/orderInfo) public class OrderInfoController {OrderInfoService orderInfoService;Autowiredprivate OrderInfoController(OrderInfoService orderInfoService) {this.orderInfoService orderInfoService;}PostMappingpublic AjaxResult saveOrderInfo(RequestBody OrderInfoBean bean) {return orderInfoService.saveOrderInfo(bean);} }OrderServiceImpl.java /*** 订单逻辑代码*/ Slf4j Service public class OrderInfoServiceImpl implements OrderInfoService {ConcurrencyLockService concurrencyLockService;/*** service类注入*/AutowiredOrderInfoServiceImpl(ConcurrencyLockService concurrencyLockService) {this.concurrencyLockService concurrencyLockService;}Overridepublic AjaxResult saveOrderInfo(OrderInfoBean bean) {long threadId Thread.currentThread().getId();final String businessNode 插入;Boolean isSuccessLock concurrencyLockService.tryLock(businessNode, bean.getOrderNo());if (!isSuccessLock) {return AjaxResult.error(加锁失败请稍后重试);}try {log.info({}开始执行业务逻辑, threadId);// TODO:模拟业务逻辑耗时Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {concurrencyLockService.unLock(businessNode, bean.getOrderNo());}return AjaxResult.success();}OverrideConcurrencyLock(businessNode 插入, businessUniqueNoKey orderNo)Transactionalpublic AjaxResult saveOrderInfoByAnnotation(OrderInfoBean bean) {// TODO:模拟业务逻辑耗时Thread.sleep(1500);return AjaxResult.success();} }pom.xml相关依赖 在dependencies中添加下列依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId /dependency dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.1.4/version /dependency !-- Mysql驱动包 -- dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId /dependency事务处理表的表结构 CREATE TABLE concurrency_lock (ID int NOT NULL AUTO_INCREMENT COMMENT 主键,THREAD_ID int DEFAULT NULL COMMENT 线程号,BUSINESS_NODE varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 操作节点,BUSINESS_UNIQUE_NO varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 单据号,CREATION_DATE datetime DEFAULT NULL COMMENT 创建时间,PRIMARY KEY (ID),UNIQUE KEY uni_business_no (BUSINESS_UNIQUE_NO,BUSINESS_NODE) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci;测试输出结果 使用Apifox并发发送5次请求可以看到实际成功获取到锁并执行的只有一个线程 17:08:00.449 [http-nio-8080-exec-1] c.r.service.impl.ConcurrencyLockServiceImpl - 40完成锁表插入 17:08:00.462 [http-nio-8080-exec-1] c.runningrookie.service.impl.OrderInfoServiceImpl - 40开始执行业务逻辑 17:08:00.573 [http-nio-8080-exec-5] c.r.service.impl.ConcurrencyLockServiceImpl - 44获取锁异常请稍后重试 17:08:00.573 [http-nio-8080-exec-4] c.r.service.impl.ConcurrencyLockServiceImpl - 43获取锁异常请稍后重试 17:08:00.573 [http-nio-8080-exec-3] c.r.service.impl.ConcurrencyLockServiceImpl - 42获取锁异常请稍后重试 17:08:00.573 [http-nio-8080-exec-2] c.r.service.impl.ConcurrencyLockServiceImpl - 41获取锁异常请稍后重试 17:08:00.574 [http-nio-8080-exec-1] c.r.service.impl.ConcurrencyLockServiceImpl - 40执行解锁完毕参考链接 gitee代码仓库地址数据库并发锁
http://www.hkea.cn/news/14277191/

相关文章:

  • 网站颜色搭配实例网站制作预付款会计分录
  • 保定满城网站建设做婚介网站可行性报告模板
  • 做钢丝绳外贸的网站wordpress调用文章内容
  • 苏州园区做网站公司网站建设与制作好学吗
  • 网站的所有权wordpress 去掉头部
  • 手机商城网站制作开源crm wordpress
  • 文章响应式网站投诉网站建设
  • 在郑州网站建设广告策划书前言范文
  • 烟台做网站谁家好武昌网站建设的公司
  • 做建站较好的网站做旅游网站的写手
  • 网站建设与优化推广方案简述程序开发的流程
  • 驻马店住房和城乡建设厅网站药材网网站技术建设
  • 邓砚谷电子商务网站建设乐山市住房和城乡规划建设局网站
  • 硬笔书法网站是谁做的在线制作图片视频
  • 汕头企业网站北京三快在线科技有限公司
  • 目前做网站需要兼容到ie8吗企业网站建设排名官网
  • 做网页收集素材常用的网站有哪些广东微信网站建设哪家专业
  • 源代码网站和模板做的区别wordpress搜索功能优化
  • 泸州公司做网站有没有接做网站私活的平台
  • 百顺网站建设线下推广小组为了推广开放文明环境地图
  • 网站注册页面郑州网站建设公司排行
  • 自学网站免费短视频运营方案书范文
  • 域名怎么创建网站吗昆明招工网站找普工作建设工作
  • 免费网站制作推广dede 网站地图模板
  • 天津塘沽网站建设公司办公室设计图平面布置图
  • 哈尔滨网站建设哈尔滨嘉兴秀洲区全网seo优化优惠
  • 奉贤北京网站建设西部网站助手
  • 怎么看网站域名海南赞赞网络科技有限公司
  • 建设工程合同备案网站1个ip可以做几个网站吗
  • 陇南比亚网站建设美美哒免费高清影院在线观看