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

网站怎么做百度优化成都关键词seo推广电话

网站怎么做百度优化,成都关键词seo推广电话,帝国网站管理系统教程,山东省交通运输厅网站开发单位目录 一、问题分析 1.1按惯例贴异常: 二、问题定位 2.1结合实际 2.2问题剖析 三、问题解答 3.1.加乐观锁 3.2.分布式锁。 一、问题分析 1.1按惯例贴异常: 187891478:618:46:21 187891478 X RECORD *****.charge_order idx_charge_order …

目录

一、问题分析

1.1按惯例贴异常:

二、问题定位 

2.1结合实际 

 2.2问题剖析

三、问题解答

3.1.加乐观锁

3.2.分布式锁。


一、问题分析

1.1按惯例贴异常:
187891478:618:46:21  187891478  X  RECORD  `*****`.`charge_order`  idx_charge_order  618  46  21  1, 0x99B18692C4, 2, 25, 771, 365

上面的异常可以通过mysql 语句:SHOW ENGINE INNODB STATUS可查到,它展示的是InnoDB 的锁信息。逐字逐句分析:

  • 187891478:618:46:21 是锁持有事务的表空间ID、页号和槽位。

  • 187891478 是事务ID。

  • X 表示该锁是 排他锁(Exclusive Lock)

  • RECORD 表示锁的是 记录锁

  • ***.charge_order 是表名。

  • idx_charge_order 是锁对应的索引。

  • 后面的数字如 1, 0x99B18692C4, 2, 25, 771, 365 是被锁定的记录内容的键值(被加锁的索引键)。

二、问题定位 

 主要的问题

  • 多个事务加锁同一条记录

    • 多个事务持有相同页的锁(例如 618:46:21,被多个事务锁住):

      187891478 187891319 187891257 187831733

      都在 idx_charge_order 索引的同一位置上加了锁,极有可能是争抢同一条数据,导致锁等待。

  • 联合索引或非主键更新

    • idx_charge_order 表示加锁操作通过 非主键索引 进行的。可能是某个字段上的查询或更新导致了间隙锁记录锁

    • 使用非唯一索引更新数据时,MySQL 会加锁相关记录,以防止幻读。

  • 行锁 + GAP 锁混合引发的死锁

    • 如果你用的是 SELECT ... FOR UPDATE 或者更新时条件不是主键,很可能会在 InnoDB 的 Next-Key Locking 策略下加上间隙锁,进而引发死锁。

  • 事务未及时提交

    • 如果多个事务对同一条记录加锁,且长时间未提交,会造成阻塞,甚至死锁。

2.1结合实际 

 那根据我自己的项目分析主要是因为定时任务叠加请求同一个接口,这个接口用了  FOR UPDATE去查询而后这个接口再进行更新。

 public void processChargingNew(OrderEntity order) {TransactionStatus transactionStatus = null;try {// 查询并加锁 charge_order 表的记录LambdaQueryWrapper<ChargeOrderEntity> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(ChargeOrderEntity::getOrderId, order.getId()).eq(ChargeOrderEntity::getIsValid, Constants.VALID).last("LIMIT 1 FOR UPDATE"); // 限制只锁一行ChargeOrderEntity chargeOrderEntity = baseMapper.selectOne(queryWrapper);if (chargeOrderEntity == null) {log.warn("充电订单不存在,orderId={}", order.getId());return;}这边省略业务逻辑……// 更新订单状态为启动中updateChargeOrderStart(chargeOrderEntity.getOrderId(), station.getId(), chargeOrderEntity);
 2.2问题剖析

1.selectOne(... FOR UPDATE) 出现在事务开启前

ChargeOrderEntity chargeOrderEntity = baseMapper.selectOne(queryWrapper); // 含 FOR UPDATE
...
transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
 

FOR UPDATE 需要在数据库事务中执行才有效!在事务开始 之前 加的锁,这意味着该锁 不是在一个有效事务上下文中产生的,实际效果不可靠,甚至不同线程间产生锁等待却得不到释放,导致死锁。 

因为定时任务每3秒会执行一次导致多个线程同时调用 这个接口,并且他们抢的是同一个 order.getId(),那么他们都会尝试 FOR UPDATE 相同的记录,哪怕只加锁一行,也可能形成排他锁等待队列

  • 如果前一个事务迟迟不提交(比如卡在业务逻辑的网络通信或外部设备响应),其他线程将被阻塞。

  • 一旦另一个线程在等待过程中,也去锁别的资源(比如 Redis、充电站表等),就很容易出现“循环等待” → 死锁。

三、问题解答

我的方案措施:

3.1.加乐观锁
  • 如果只是为了防止并发更新同一条订单数据,可以用乐观锁(如版本号 version 字段 + where version = ?)来实现并发控制。这里有个细节就是项目必须是Spring Boot 集成 MyBatis-Plus,配置乐观锁插件。

  • Spring Boot + MyBatis-Plus 项目结构

    <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.x</version>
    </dependency>
    

    需要在 配置类 中添加一个 @Bean,如下

    @Configuration
    public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加乐观锁插件interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
    }
    

    放在任何一个 @Configuration 类里都可以,比如项目里的 MyBatisPlusConfig.java 或者 PersistenceConfig.java 等。


    注意事项:

  • MyBatis-Plus 3.4.x 以前版本 用的是旧插件注册方式。

  • 新版 3.5.x 起,都统一使用 MybatisPlusInterceptor 插件机制。

  • 插件加载顺序重要,如果还有分页插件,也得放进去,比如:

interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

配好之后,使用方式不变 

@Version
private Integer version;

 代码示例:

// 查询并加锁 charge_order 表的记录
LambdaQueryWrapper<ChargeOrderEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ChargeOrderEntity::getOrderId, order.getId()).eq(ChargeOrderEntity::getIsValid, Constants.VALID).last("LIMIT 1");// 去掉 FOR UPDATE,改用乐观锁ChargeOrderEntity chargeOrderEntity = baseMapper.selectOne(queryWrapper);

 只要调用 updateById() 等方法,MyBatis-Plus 自动帮你在 SQL 加上 version = ? 的条件并做自增。(大功告成!!)

3.2.分布式锁。

// 调整顺序:
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
    // 查询并加锁必须放在事务内
    ChargeOrderEntity chargeOrderEntity = baseMapper.selectOne(
        new LambdaQueryWrapper<ChargeOrderEntity>()
            .eq(ChargeOrderEntity::getOrderId, order.getId())
            .eq(ChargeOrderEntity::getIsValid, Constants.VALID)
            .last("LIMIT 1 FOR UPDATE")
    );

    // 其余逻辑...
 

 如果是多实例部署(集群中多个服务节点同时跑这个定时任务)这种情况下就建议加上Redis 分布式锁,防止多个节点同时处理同一个订单。可以在任务开始时做类似以下锁控制:

String lockKey = "prepare:charge:order:" + order.getId();
boolean isLocked = redisUtils.tryLock(lockKey, 0, 30); // 不等待,锁30秒
if (!isLocked) {log.info("订单正在处理,跳过 orderId={}", order.getId());return null;
}try {// 执行业务逻辑} finally {redisUtils.releaseLock(lockKey);
}

这样可以防止集群中多个任务节点同时操作同一条订单。

http://www.dtcms.com/wzjs/141093.html

相关文章:

  • 宝鸡企业网站建设免费的seo优化工具
  • 洛阳青峰网络公司做网站短视频营销方式有哪些
  • 禁用软件app大全长沙百度推广优化排名
  • 河东手机网站建设保定百度首页优化
  • 扁平风格企业网站源码推广百度百科
  • 网站如何做抖音推广连云港seo优化
  • 深圳网站seo优化山西网络推广
  • 网站开发人员结构软文写作经验是什么
  • 青团智慧团建登录入口深圳市企业网站seo营销工具
  • 阳明拍卖公司网站网络营销的核心是什么
  • 专做老酒的网站搜索引擎优化的意思
  • 福田做网站的绍兴seo排名外包
  • 品牌家装十大排名搜索引擎优化怎么做的
  • 沧州市高速公路建设管理局网站代发广告平台
  • 郑州建网站公司什么是搜索引擎优化?
  • 推广网站挣钱国内搜索引擎排名第一的是
  • 金蝶软件有限公司seo综合查询什么意思
  • asp.net 做网站大数据智能营销
  • 做网站的风险seo sem推广
  • 网站网站制作公司哪家好线上推广有哪些
  • 做网站没有固定电话销售渠道
  • 赣州做网站j视频网站推广
  • 北京外贸网站建设公司seo专家招聘
  • 工信部个人备案网站可信吗营销活动推广策划
  • 网站关键词分隔360外链
  • 嵊州网站制作seo关键词排名优化销售
  • 网站建设中图片怎么插入百度搜索引擎关键词
  • 深圳网站建设公司设计sem是什么
  • 三亚门户网站网站结构优化
  • 酒东莞网站建设技术支持站长工具外链查询