JAIN SLEE 中Container Managed Persistent (CMP)

news2024/9/21 7:48:06

JAIN SLEE 中,Container Managed Persistent (CMP) 是一种机制,它允许应用程序开发人员定义一些持久化的状态,而不需要自己去编写代码来保存或恢复这些状态。容器(应用服务器)会自动处理这些数据的存储、加载和恢复。CMP 的使用在某些场景中非常方便,例如处理电信服务中的会话状态、活动数据等,它能够保证系统即使重启或出现故障,数据也能自动恢复。

1. 什么是 CMP?

  • Container(容器):是指运行应用程序的环境,它可以是一个应用服务器,如 JBoss、WebLogic 等,它负责管理应用程序的生命周期、资源和组件的交互。
  • Managed(管理):容器会自动管理应用程序的一些特定资源,比如存储和恢复对象状态。
  • Persistent(持久化):是指将数据保存到某种存储介质上(通常是数据库),即使应用程序停止或崩溃,数据也不会丢失。

2. CMP 的工作原理

在 JAIN SLEE 中,SBB (Service Building Block) 是一个核心组件,SBB 包含服务逻辑和状态。CMP 机制帮助 SBB 将这些状态数据自动持久化。开发者只需通过定义 CMP 字段,容器会在需要时自动将它们保存到数据库中,而当 SBB 恢复时,容器会自动从数据库加载这些数据。

3. 如何使用 CMP —— 详细示例

1. 定义 SBB 类和 CMP 字段

首先,你需要在 SBB 中定义需要持久化的状态字段。通常,这些字段通过 abstract 方法定义,并且容器将负责管理它们的存取操作。

import javax.slee.Sbb;
import javax.slee.ActivityContextInterface;

public abstract class ConferenceSbb implements Sbb {

    // 定义持久化的 CMP 字段
    public abstract void setConferenceId(String id);  // 设置会议ID
    public abstract String getConferenceId();         // 获取会议ID

    public abstract void setParticipantCount(int count);  // 设置参与者数量
    public abstract int getParticipantCount();            // 获取参与者数量

    // 处理电话呼入事件
    public void onCallStart(CallEvent event, ActivityContextInterface aci) {
        int currentCount = getParticipantCount();  // 获取当前参与者数量
        setParticipantCount(currentCount + 1);     // 增加参与者数量
    }

    // 处理电话挂断事件
    public void onCallEnd(CallEvent event, ActivityContextInterface aci) {
        int currentCount = getParticipantCount();  // 获取当前参与者数量
        setParticipantCount(currentCount - 1);     // 减少参与者数量
    }
}

解释

  • getConferenceId()getParticipantCount() 是两个 CMP 字段,通过抽象方法定义,容器会管理这些字段的存储和恢复。
  • onCallStart()onCallEnd() 事件处理方法修改 CMP 字段的值(例如电话会议的参与人数),并由容器负责将这些修改持久化到数据库中。
2. 配置持久化(CMP 配置)

为了让容器知道需要管理哪些字段以及如何持久化它们,需要在 SBB 的部署描述文件中进行配置。

在 JAIN SLEE 中,通常会在 sbb-jar.xml 中指定 CMP 字段。假设我们需要持久化 ConferenceIdParticipantCount,配置如下:

<sbb>
    <sbb-name>ConferenceSBB</sbb-name>
    <sbb-class-name>com.example.ConferenceSbb</sbb-class-name>

    <!-- 定义 CMP 字段 -->
    <cmp-fields>
        <cmp-field>
            <cmp-field-name>conferenceId</cmp-field-name>
        </cmp-field>
        <cmp-field>
            <cmp-field-name>participantCount</cmp-field-name>
        </cmp-field>
    </cmp-fields>
</sbb>

解释

  • sbb-name 是 SBB 的名字,sbb-class-name 是 SBB 类的完整路径。
  • <cmp-fields> 标签定义了需要由容器管理的字段。
  • 每个 <cmp-field> 标签表示一个需要持久化的字段,比如 conferenceIdparticipantCount
3. 配置数据源

CMP 通常依赖于数据库进行持久化,因此需要在应用服务器中配置一个数据源,容器会使用该数据源进行数据库操作。

在 JBoss 这样的应用服务器中,你需要配置一个数据源(例如 datasource.xml):

<datasources>
    <datasource>
        <jndi-name>java:/MySbbDatasource</jndi-name>
        <connection-url>jdbc:mysql://localhost:3306/sbb_db</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <user-name>root</user-name>
        <password>password</password>
    </datasource>
</datasources>

解释

  • jndi-name 是数据源的名称,JAIN SLEE 容器会通过这个名字查找数据源并与数据库进行交互。
  • connection-url 是数据库的连接地址,user-namepassword 是数据库的认证信息。

4. CMP 的优点

  • 自动管理:开发人员不需要手动编写持久化逻辑,容器会自动保存和恢复数据。
  • 简化代码:业务逻辑与持久化逻辑分离,使代码更清晰。
  • 持久化保障:在系统重启或故障后,数据不会丢失,因为容器会自动将状态存储到持久性存储中。

5. 小结

Container Managed Persistence (CMP) 在 JAIN SLEE 中提供了一种方便的方式,帮助开发人员将 SBB 的状态数据自动保存到数据库中,并在需要时自动恢复。这种机制解放了开发者,使其专注于业务逻辑,而不用关心底层的数据存储和恢复操作。

应用步骤总结

  1. 在 SBB 中定义抽象的 CMP 字段。
  2. 在部署描述文件(如 sbb-jar.xml)中指定哪些字段需要持久化。
  3. 配置容器的数据源,容器将自动管理状态的存储和恢复。

通过这些步骤,你可以轻松实现 SBB 的持久化管理,确保系统的健壮性和数据持久性。


JAIN SLEE 编码实现业务过程中,Container Managed Persistence (CMP) 提供了许多便利的功能,但在实际使用中,合理使用和优化 CMP 可以帮助提高系统的性能和健壮性。以下是一些 CMP 的高级用法和技巧,帮助在复杂的业务场景中更好地使用 CMP

1. Lazy Loading(延迟加载)

延迟加载 是一种在实际需要时才加载数据的技术。对于 CMP 字段,容器会在需要访问时从数据库中加载这些数据,而不是一次性全部加载。这有助于减少数据库的访问频率,从而提升性能。

使用场景

  • 当有些字段可能不经常被访问时,可以让容器根据需求加载它们,而不在每次调用时都去加载不必要的数据。

实现方式

  • 虽然 CMP 本身不需要显式地配置延迟加载,但你可以通过尽量减少对不必要字段的访问,来间接触发延迟加载。也可以通过设计 SBB 来只访问必要的字段,降低系统的负载。

2. Optimistic Locking(乐观锁)

乐观锁 是一种并发控制机制,用于防止在多线程或分布式环境中发生数据冲突。默认情况下,CMP 依赖容器处理并发事务。如果多个事务同时修改同一个 CMP 字段,可能会引发数据一致性问题。

高级用法

  • 通过实现乐观锁机制,你可以防止“脏写”(即事务间修改冲突)问题。这通常是通过为 CMP 字段添加版本号或时间戳来跟踪数据的变化。
  • 在进行更新操作时,检查当前版本号或时间戳是否匹配,确保数据在更新时没有被其他事务修改。

实现方法

  • 在 SBB 中为某个字段(如 version 字段)设置版本控制,更新时确保版本的一致性。
public abstract class MySbb implements Sbb {

    // 定义一个版本控制的 CMP 字段
    public abstract int getVersion();
    public abstract void setVersion(int version);

    public void updateData() {
        int currentVersion = getVersion();
        // 更新数据逻辑
        // 检查版本号是否匹配
        if (currentVersion == expectedVersion) {
            setVersion(currentVersion + 1); // 更新版本号
        } else {
            throw new OptimisticLockException("Data has been modified by another transaction.");
        }
    }
}

3. Transactional Consistency(事务一致性)

JAIN SLEE 支持 Java 事务 API(JTA),事务机制对于确保 CMP 数据的一致性非常重要。在使用 CMP 的时候,通常会结合 JTA 来确保数据在发生错误时能自动回滚。

技巧

  • 在业务逻辑中处理 CMP 字段时,应该尽量在事务中进行操作,这样可以确保即使发生了错误或异常,数据状态也能被正确回滚,不会出现部分更新的情况。

实现方法

  • 使用 @TransactionManagement 注解或在 SBB 中显式地控制事务的边界。
import javax.transaction.UserTransaction;

public abstract class MySbb implements Sbb {

    public void someBusinessMethod() {
        UserTransaction tx = ctx.getUserTransaction();
        try {
            tx.begin();
            // 修改 CMP 数据
            setMyCmpField("new value");
            // 其他业务逻辑
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }
    }
}

4. Preloading(预加载)和 Caching(缓存)

预加载缓存 是提升性能的重要技巧。对于频繁访问的 CMP 字段,频繁的数据库查询可能成为性能瓶颈。通过预加载或缓存数据,可以大幅降低数据库访问的频率。

使用场景

  • 当某些字段被频繁读取时,可以考虑将这些字段在内存中缓存,减少数据库的访问开销。

实现方法

  • 在 SBB 启动时预加载一些重要的 CMP 数据到内存中,并在需要时直接从缓存读取。
public abstract class CachedSbb implements Sbb {

    private Map<String, Object> cache = new HashMap<>();

    public void loadDataIntoCache() {
        String data = getMyCmpField();
        cache.put("key", data);
    }

    public String getCachedData() {
        return cache.get("key");
    }
}

5. Avoid Overuse of CMP(避免过度使用 CMP)

尽管 CMP 自动处理持久化非常方便,但过度依赖 CMP 可能会导致性能问题。并不是所有的状态都需要持久化,尤其是那些短期存在、生命周期较短的状态,建议直接存储在内存中,而不是每次都持久化到数据库。

技巧

  • 将短期数据或临时状态保存在内存中,而不是使用 CMP,这样可以减轻数据库的负担。
  • 仅对重要的、需要持久化的业务状态使用 CMP。

示例
假设有一个通话的状态数据,但通话结束后该状态可以被丢弃,那么不需要将这个状态存储到数据库中:

public class CallSbb implements Sbb {

    private transient String callSessionId;  // 临时数据,不需要持久化

    public void onCallStart() {
        callSessionId = generateSessionId();
        // 其他逻辑
    }

    public void onCallEnd() {
        callSessionId = null;  // 通话结束后不再需要此状态
    }
}

6. Custom Database Mapping(自定义数据库映射)

在一些场景中,默认的 CMP 映射可能不能满足业务需求。可以通过自定义映射,将 CMP 字段与数据库表中的特定列或表关联。

高级用法

  • 通过配置文件或注解,指定某些 CMP 字段如何映射到数据库中的列。例如,将某个复杂对象序列化后存储到一个特定的数据库列中。

实现方法
在部署描述文件中,你可以指定数据库表名、列名以及 CMP 字段的映射关系。某些应用服务器支持通过 XML 或注解定义自定义映射。

<cmp-field>
    <cmp-field-name>customField</cmp-field-name>
    <column-name>CUSTOM_COLUMN</column-name>
</cmp-field>

7. CMP 与分布式系统的结合

在分布式环境中,多个节点可能同时访问或修改 CMP 数据。为了防止冲突,JAIN SLEE 提供了一些机制确保数据的一致性。

技巧

  • 结合分布式事务,确保多个节点的操作不会产生冲突。
  • 使用全局事务管理器(如 JTA)协调分布式系统中的事务,防止“脏读”和“脏写”问题。

8. 定期清理持久化数据

有些数据可能只在特定时间内有效,比如会话数据或临时的业务数据。为了避免 CMP 数据库膨胀,需要定期清理这些不再需要的数据。

技巧

  • 设置定期任务(如 Cron 作业)清理过期或无效的持久化数据,确保数据库的效率不会被过量的历史数据影响。

总结

CMP 是 JAIN SLEE 中非常强大且方便的持久化机制,但要有效使用它,开发者需要关注以下几点:

  • 合理使用延迟加载和缓存来提升性能。
  • 使用乐观锁机制防止并发冲突。
  • 结合事务管理,确保数据一致性。
  • 谨慎选择需要持久化的数据,避免不必要的数据库访问。
  • 定期清理不再需要的数据,保持系统的健壮性。

通过这些技巧,开发者可以在使用 CMP 时更好地管理状态和数据库交互,确保系统在高并发和分布式环境中的稳定性和高效性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2151731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

秒懂Linux之共享内存

目录 共享内存概念 模拟实现共享内存 创建key阶段 ​编辑创建共享内存阶段 删除共享内存阶段 查看共享内存属性阶段 挂接共享内存到进程阶段 取消共享内存与进程挂接阶段 进程通信阶段 添加管道改进版 共享内存函数 shmget函数 shmat函数 shmdt函数 shmctl函数 共享内存概念 共…

第二十一节:学习Redis缓存数据库的Hash操作(自学Spring boot 3.x的第五天)

这节记录下Redis的Hash操作。主要是opsForHash方式和boundHashOps方式。 boundHashOps和opsForHash都是Spring Data Redis中用于操作Redis哈希数据结构的方法&#xff0c;但它们在使用方式和场景上存在一些区别。 boundHashOps 使用方式&#xff1a; boundHashOps方法通过Redi…

【第十三章:Sentosa_DSML社区版-机器学习聚类】

目录 【第十三章&#xff1a;Sentosa_DSML社区版-机器学习聚类】 13.1 KMeans聚类 13.2 二分KMeans聚类 13.3 高斯混合聚类 13.4 模糊C均值聚类 13.5 Canopy聚类 13.6 Canopy-KMeans聚类 13.7 文档主题生成模型聚类 13.8 谱聚类 【第十三章&#xff1a;Sentosa_DSML社…

C#基于SkiaSharp实现印章管理(8)

上一章虽然增加了按路径绘制文本&#xff0c;支持按矩形、圆形、椭圆等路径&#xff0c;但测试时发现通过调整尺寸、偏移量等方式不是很好控制文本的位置。相对而言&#xff0c;使用弧线路径&#xff0c;通过弧线起始角度及弧线角度控制文本位置更简单。同时基于路径绘制文本时…

Chainlit集成LlamaIndex实现知识库高级检索(简单融合寻回器)

检索原理 ** 简单融合寻回器 ** 简单融合寻回原理&#xff0c;是利用多个检索器&#xff0c;融合查询最终的结果返回给LLM。此检索器还将通过生成与原始问题相关的问题&#xff0c;用相关问题再次检索多个检索器的数据&#xff0c;把原始问题和相关问题经过多个检索器检索结果…

Relations Prediction for Knowledge Graph Completion using Large Language Models

文章目录 题目摘要简介相关工作方法论实验结论局限性未来工作 题目 使用大型语言模型进行知识图谱补全的关系预测 论文地址&#xff1a;https://arxiv.org/pdf/2405.02738 项目地址&#xff1a; https://github.com/yao8839836/kg-llm 摘要 知识图谱已被广泛用于以结构化格式表…

高级java每日一道面试题-2024年9月20日-分布式篇-什么是CAP理论?

如果有遗漏,评论区告诉我进行补充 面试官: 什么是CAP理论&#xff1f; 我回答: 在Java高级面试中&#xff0c;CAP理论是一个经常被提及的重要概念&#xff0c;它对于理解分布式系统的设计和优化至关重要。CAP理论是分布式系统理论中的一个重要概念&#xff0c;它描述了一个分…

【数学分析笔记】第3章第2节 连续函数(4)

3. 函数极限与连续函数 3.2 连续函数 3.2.9 反函数的连续性定理 【定理3.2.2】【反函数连续性定理】设 y f ( x ) yf(x) yf(x)在闭区间 [ a , b ] [a,b] [a,b]上连续且严格单调增加&#xff0c;设 f ( a ) α , f ( b ) β f(a)\alpha,f(b)\beta f(a)α,f(b)β&#xff0…

仓颉编程入门

#体验华为仓颉编程语言# 仓颉发布的第一时间&#xff0c;就申请了测试。昨天发现申请通过 &#xff0c;果断下载SDK体验一下。 废话不多说&#xff0c;从下载完开始&#xff0c;下面这个图&#xff0c;就是下载的文件&#xff1a; 看文件夹样子跟c/c套路差不多。bin目录是cjc…

linux安装nginx+前端部署vue项目(实际测试react项目也可以)

&#x1f9f8;本篇博客作者测试上线过不下5个项目&#xff0c;包括单纯的静态资源&#xff0c;vue项目和react项目&#xff0c;包好用&#xff0c;请放心使用 &#x1f4dc;作者首页&#xff1a;dream_ready-CSDN博客 &#x1f4dc;有任何问题都可以评论留言&#xff0c;作者将…

什么是大模型的泛化能力?

大模型的泛化能力指的是模型在未见过的数据上表现的能力&#xff0c;即模型不仅能在训练数据上表现良好&#xff0c;也能在新的、未知的数据集上保持良好的性能。这种能力是衡量机器学习模型优劣的重要指标之一。 泛化能力的好处包括但不限于&#xff1a; 提高模型的适应性&a…

基于uniapp的民宿酒店预订系统(后台+小程序)

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

F28335中断系统

1 中断介绍 1.1 中断概念 1.2 TMS320F28335 中断概述

CUDA并行架构

一、CUDA简介 CUDA(Compute Unified Device Architecture)是一种由NVIDIA推出的通用并行计算架构&#xff0c;该架构使GPU(Graphics Processing Unit)能够对复杂的计算问题做性能速度优化。 二、串并行模式 高性能计算的关键是利用多核处理器进行并行计算。 串行模式&#…

使用LangGPT提示词让大模型比较浮点数

使用LangGPT提示词让大模型比较浮点数 背景介绍环境准备创建虚拟环境安装一些必要的库安装其他依赖部署大模型启动图形交互服务设置提示词与测试 LangGPT结构化提示词 背景介绍 LLM在对比浮点数字时表现不佳&#xff0c;经验证&#xff0c;internlm2-chat-1.8b (internlm2-cha…

Excel-时间取整,工作有效时长计算

在计算考勤时&#xff0c;打卡时间不是整点&#xff0c;上班时间是遵循整点开始计算的&#xff0c;员工提前打卡&#xff0c;所以要用到时间向上取整。 上班取整&#xff1a; 使用CEILING函数可实现该需求&#xff0c;参考以下公式&#xff0c;第一个参数为上班打卡时间&#…

MySQL篇(窗口函数/公用表达式(CTE))(持续更新迭代)

目录 讲解一&#xff1a;窗口函数 一、简介 二、常见操作 1. sumgroup by常规的聚合函数操作 2. sum窗口函数的聚合操作 三、基本语法 1. Function(arg1,..., argn) 1.1. 聚合函数 sum函数&#xff1a;求和 min函数 &#xff1a;最小值 1.2. 排序函数 1.3. 跨行函数…

一文读懂SpringCLoud

一、前言 只有光头才能变强 认识我的朋友可能都知道我这阵子去实习啦&#xff0c;去的公司说是用SpringCloud(但我觉得使用的力度并不大啊~~)… 所以&#xff0c;这篇主要来讲讲SpringCloud的一些基础的知识。(我就是现学现卖了&#xff0c;主要当做我学习SpringCloud的笔记吧&…

英集芯IP5902:集成电压可调异步升压转换充电管理功能的8位MCU芯片

英集芯IP5902是一款集成了9V异步升压转换、锂电池充电管理及负端NMOS管的8-bit MCU芯片&#xff0c;外壳采用了SOP16封装形式&#xff0c;高集成度和丰富的功能使其在应用时只需很少的外围器件&#xff0c;就能有效减小整体方案的尺寸&#xff0c;降低BOM成本&#xff0c;为小型…

Vue使用axios实现Ajax请求

1、什么是 axios 在实际开发过程中&#xff0c;浏览器通常需要和服务器端进行数据交互。而 Vue.js 并未提供与服务器端通信的接口。从 Vue.js 2.0 版本之后&#xff0c;官方推荐使用 axios 来实现 Ajax 请求。axios 是一个基于 promise 的 HTTP 客户端。 关于 promise 的介绍…