回滚莫队?滚滚滚滚起来!

本文详细介绍了一种称为“回滚莫队”的算法,该算法适用于处理特定类型的区间查询问题。文章通过两个特别之处——针对同一块内的左右端点进行暴力求解以及枚举每一块来统计答案的方式,生动地解释了回滚过程。最后提供了一道练习题供读者实践。


 回滚莫队

             这名字真的取的有意思,一开始还不觉得,学了之后发现他真的在回滚.我们回滚莫队排序是按之前的莫队一样将询问  左块右位置 的来排序.
        回滚问题特别之处在哪里?
        他在滚.

    特别之处1

              我们对于左右端点都在同一块里的,直接暴力for 1遍统计答案,复杂度根号n.

    特别之处2

              我们是枚举每一块来统计答案的.此时我们只处理左端点在此块,右端点在右块的询问,左右同块的见1.我们把ql指针指向下一块的开头,qr指针指向这一块的末尾.对于此本块询问,我们先将qr指针向右移更新信息直到此询问的右端点.(当我们处理下一个询问的时候,qr只需要继续右移就可以了,因为询问左端点都同块的时候,我们是按右端点位置从小到大排序的,所以单调递增).
        这里好像没有回滚,并且由于qr单调递增,区间扩大,并没有删除操作.
        但是我还没讲ql.
        本块包含询问的左端点一定在ql左边(见ql定义).我们就将ql向左移更新答案(此时区间仍然在扩大,只有更新操作没有删除操作),到了询问的左端点,统计答案.
        然后就开始滚了,并且是回滚.ql向左到达询问左端点后,向右往初始位置(见ql定义)移,删除之前一路滚过来所更新的信息.然后ql回滚回来,qr仍不动,处理下个询问.
        所以就是 qr向右移动更新信息到询问右端点->ql向左滚 边滚边更新 至询问左端点,然后处理此区间答案,ql回滚删除之前一路滚来更新的信息,回到初位置->处理(下个询问->本块询问处理完->枚举下个块.
        回滚得十分形象.
        一道练手题:点这里(可以用分快做但最好用回滚莫队练练手,看了我的代码你就懂了).
处理 MySQL 导致 Java 事务回滚问题可从多方面着手。 首先要确保存储引擎使用支持事务的 InnoDB。因为 MySQL 的 MyISAM 模式不支持事务,会导致事务回滚失效,将其改为 InnoDB 模式事务才能生效 [^3]。 对于注解使用方面,要保证在 Java 代码中正确使用事务注解。在 Spring 框架里,常使用 `@Transactional` 注解来管理事务。不过要注意,注解的参数配置需正确,像 `rollbackFor` 参数可指定哪些异常触发事务回滚。若方法里抛出的异常不在 `rollbackFor` 指定范围内,事务可能不会回滚。例如在 Service 层的方法上添加 `@Transactional(rollbackFor = Exception.class)`,能让事务在遇到任何异常时都回滚 [^3]。 异常处理也很关键。在 Java 代码里,要正确捕获和处理异常,保证异常能触发事务回滚。如果在代码里捕获了异常却未重新抛出,或者捕获的异常类型与 `@Transactional` 注解指定的回滚异常类型不匹配,事务就不会回滚。比如代码中手动捕获了异常但没做后续处理,就可能导致事务不回滚,所以应保证异常能正常传递,让事务管理器感知到异常从而触发回滚 [^3]。 锁和并发控制也不容忽视。在高并发场景下,事务可能因锁冲突而回滚。要合理设计数据库表结构和事务逻辑,减少锁的竞争。例如,采用乐观锁或行级锁替代表级锁,降低锁冲突的概率,保证事务顺利执行。 日志记录和监控也很重要。在 MySQL 和 Java 应用里添加详细的日志记录,方便排查问题。可以记录事务的开始、提交、回滚等操作,以及相关的 SQL 语句和异常信息。同时,利用监控工具监控数据库的性能和事务状态,及时发现并解决潜在问题。 下面是一个简单的 Java 代码示例,展示如何正确使用 `@Transactional` 注解: ```java import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class UsersService { @Autowired private TUserMapper tUserMapper; @Transactional(rollbackFor = Exception.class) public void deleteUser(Long uid) { tUserMapper.deleteByPrimaryKey(uid); // 模拟异常 int i = 1 / 0; } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值