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

做个网站多少钱合适深圳装修公司排行榜

做个网站多少钱合适,深圳装修公司排行榜,网络营销的含义特点,培训网站平台怎样做在分布式系统中,为了确保业务操作的一致性和数据安全,我们常常需要对多个资源(如订单、库存、商品等)同时加锁。虽然 Redisson 提供的单一资源锁(RLock)使用简单,但在业务逻辑涉及多个资源时&am…

在分布式系统中,为了确保业务操作的一致性和数据安全,我们常常需要对多个资源(如订单、库存、商品等)同时加锁。虽然 Redisson 提供的单一资源锁(RLock)使用简单,但在业务逻辑涉及多个资源时,仅靠单个锁显得力不从心。为此,Redisson 提供了**联锁(MultiLock)**机制,它能把多个 RLock 组合成一个整体锁,只有当所有子锁都成功加锁后,才能算真正拿到了锁。


1. RedissonMultiLock 的基本原理

RedissonMultiLock 的设计思路其实很简单,主要有以下几个特点:

  • 整体加锁:只有当传入的所有 RLock 都成功加锁,才认为联锁获取成功;否则,已经拿到的子锁会被全部释放,并重新尝试加锁。
  • 自动续期机制:即便设置了无限期持有(leaseTime 为 -1),Redisson 内部会启动看门狗机制自动延长锁的有效期,避免业务处理时间过长而导致锁被误释放。
  • 失败策略:在加锁过程中,如果任何一个子锁获取失败(例如遇到 Redis 响应超时),所有已获取的子锁都会被释放,然后重试,直到在规定等待时间内全部获得锁。
  • 底层实现:联锁主要依赖于各个 RLock 的 tryLock(waitTime, leaseTime, unit) 方法,通过依次遍历各个锁来实现加锁,释放时依次调用每个锁的 unlock() 方法。

适用场景

  • 分布式订单处理:在处理订单时同时锁定订单、库存、商品等多个关键资源,确保在高并发环境下数据始终保持一致。
  • 跨服务协同:多个服务(甚至分布在不同 Redisson 客户端)同时操作同一批资源时,联锁可以确保所有服务拿到锁后再开始操作。
  • 复杂事务控制:当一个操作涉及多个子步骤,需要保证要么全部成功要么全部回滚时,使用联锁能够确保各个资源都处于受控状态。

2. 优化后的代码示例

下面的代码展示了如何在 Spring Boot 环境下使用 RedissonMultiLock。示例不仅说明了如何加锁、执行业务逻辑和安全释放锁,还对等待时间和租约时间的设置做了详细说明。

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.RedissonMultiLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;/*** 示例展示了如何使用 RedissonMultiLock 将多个 RLock 组合成一个整体锁,* 从而确保只有当所有子锁都成功加锁后才执行业务逻辑。** 使用场景例如分布式订单系统中,同时锁定多个资源,确保操作的原子性。** 注意:* 1. 若任意一个子锁获取失败,会释放已获得的所有锁并重试;* 2. 释放锁前,最好判断当前线程是否持有该锁,避免误解锁导致异常;* 3. 当 leaseTime 为 -1 时,系统会自动续期锁的有效期(看门狗机制)。*/
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedissonMultiLockTest {@Autowiredprivate RedissonClient redissonClient;// 创建一个固定大小的线程池,用于并发测试(实际使用时可根据需要调整线程数)private final ExecutorService executorService = Executors.newFixedThreadPool(3);@Afterpublic void tearDown() {// 测试结束后关闭线程池,防止资源泄露executorService.shutdown();}/*** 测试 RedissonMultiLock 的基本用法:* - 任务1尝试同时获取 lock1 和 lock2,成功拿到联锁后开始执行业务逻辑;* - 任务2和任务3分别尝试获取 lock1 与 lock2,预期因联锁占用而拿不到锁。** 说明:* 1. 联锁加锁时的等待时间根据锁数量设置(此处为 locks.size() * 1500 毫秒左右);* 2. 若 leaseTime 为 -1,则启用看门狗机制,自动续期防止锁超时。*/@SneakyThrows@Testpublic void testTryMultiLock() {// 初始化单个锁RLock lock1 = redissonClient.getLock("lock1");RLock lock2 = redissonClient.getLock("lock2");// 创建联锁:只有 lock1 和 lock2 都加锁成功才算成功RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2);// 任务1:尝试获取联锁Runnable task1 = () -> {boolean locked = false;try {// 参数说明:// waitTime:最大等待时间(这里计算得出,如2个锁时大约3000~4500毫秒)// leaseTime:租约时间,-1 表示启用看门狗自动续期if (multiLock.tryLock(1L, 10L, TimeUnit.SECONDS)) {locked = true;log.info("【任务1】成功获取联锁,开始执行业务逻辑...");// 模拟业务处理Thread.sleep(2000);log.info("【任务1】业务处理完毕。");} else {log.warn("【任务1】获取联锁失败。");}} catch (InterruptedException e) {Thread.currentThread().interrupt();log.error("【任务1】执行过程中被中断", e);} finally {if (locked) {// 释放联锁(会依次释放 lock1 和 lock2)multiLock.unlock();log.info("【任务1】联锁已释放。");}}};// 任务2:尝试获取 lock1(由于联锁中已锁定 lock1,预计获取失败)Runnable task2 = () -> {boolean locked = false;RLock lock = redissonClient.getLock("lock1");try {if (lock.tryLock(0L, 5L, TimeUnit.SECONDS)) {locked = true;log.info("【任务2】成功获取 lock1,开始执行业务逻辑...");Thread.sleep(2000);log.info("【任务2】业务处理完毕。");} else {log.warn("【任务2】获取 lock1 失败。");}} catch (InterruptedException e) {Thread.currentThread().interrupt();log.error("【任务2】执行过程中被中断", e);} finally {if (locked && lock.isHeldByCurrentThread()) {lock.unlock();log.info("【任务2】lock1 已释放。");}}};// 任务3:尝试获取 lock2(同上,预计获取失败)Runnable task3 = () -> {boolean locked = false;RLock lock = redissonClient.getLock("lock2");try {if (lock.tryLock(0L, 5L, TimeUnit.SECONDS)) {locked = true;log.info("【任务3】成功获取 lock2,开始执行业务逻辑...");Thread.sleep(2000);log.info("【任务3】业务处理完毕。");} else {log.warn("【任务3】获取 lock2 失败。");}} catch (InterruptedException e) {Thread.currentThread().interrupt();log.error("【任务3】执行过程中被中断", e);} finally {if (locked && lock.isHeldByCurrentThread()) {lock.unlock();log.info("【任务3】lock2 已释放。");}}};// 先提交任务1以确保先拿到联锁,再依次提交任务2和任务3Future<?> future1 = executorService.submit(task1);Thread.sleep(20);Future<?> future2 = executorService.submit(task2);Future<?> future3 = executorService.submit(task3);// 等待所有任务结束future1.get();future2.get();future3.get();}/*** 简单测试:确保异步任务能正常执行,避免主线程提前结束。*/@SneakyThrows@Testpublic void testSimpleExecution() {Runnable task = () -> {try {log.info("【任务】开始执行...");Thread.sleep(2000);log.info("【任务】执行结束。");} catch (InterruptedException e) {Thread.currentThread().interrupt();log.error("【任务】执行过程中被中断", e);}};Future<?> future = executorService.submit(task);future.get();}
}

3. 总结

  • RedissonMultiLock 可以帮助我们同时锁定多个关键资源,只有所有子锁都成功后才执行后续操作,保证数据一致性。
  • 建议
    • 调用加锁方法前,根据实际情况设置合适的等待时间和租约时间,充分利用看门狗机制防止锁误释放;
    • 释放锁时最好判断当前线程是否持有该锁,以避免误解锁导致异常;
  • 应用场景:适用于分布式订单处理、跨服务协同操作和复杂事务控制等需要同时操作多个资源的场景。
http://www.dtcms.com/wzjs/595434.html

相关文章:

  • 做瓷砖在什么网站上找素材好网站开发命名规范
  • 网站推广公司推荐网站建设mrd文档模板
  • 网站建设 后期维护什么是企业邮箱怎么申请
  • 有没有做gif的专门网站东莞网站关键词
  • 骑行网站模板做网站能赚钱吗表情包
  • 黄埔区做网站网站的栏目结构简图怎么做
  • 宣传片制作公司有哪些类型电脑网络优化软件
  • 网站开发用哪个程序网站没备案
  • 网站搭建完手机访问网络推广是以企业产品或服务
  • 网站设计主流尺寸python好还是wordpress
  • 做flash网站的软件建站之星模板的使用
  • 南京市规划建设展览馆网站福州百度代理
  • 网站建设需要哪些岗位网站建设需要哪些人才
  • 旅游网站建设需求说明书深圳福田区有哪些大公司
  • 网站数据库在空间吗wordpress不显示
  • 内容网站最新好用的cms军事新闻视频在线观看
  • 怎样批量做地级市网站广州网站建设 易点
  • 建设企业网站方法中国新闻社是什么单位
  • wordpress安装ssl后网站404购物网站开发 书籍
  • 网站开发哪些无经验培训 网页设计学员
  • 制作婚纱摄影网站管理图甘肃肃第八建设集团网站
  • 网站返回404是什么意思怎么登录智慧团建
  • 做二手交易网站如何盈利智慧团建官网登录口入口
  • 免费动画制作网站网站建设 人和商圈
  • 岳麓 网站设计wordpress ip排行榜
  • 企业网站设计过程中自学网官方网站入口
  • 谷歌网站开发客户百度地图怎么搜街景
  • wordpress e-commerce themesiis 网站 优化
  • p2p贷款网站制作做网站上传的图片显示变形
  • 做网站的电话聊天软件怎么做