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

EJB如何管理事务

目录

参考文章

前言:

1. @TransactionManagement

2. @TransactionAttribute

3. @ApplicationException

4. @EJB

5. @Stateless 和 @Stateful

6. @PostConstruct 和 @PreDestroy

7.不使用容器管理事务时,可以使用 @Stateless 吗

1. @Stateless 与事务管理的关系

2. 使用 @Stateless 并启用 Bean 管理事务

3. 如何在 @Stateless 中使用 Bean 管理事务

4. 推荐做法

5. @Stateful 与 Bean 管理事务

总结1

总结2


===

参考文章

JPA、EJB、事务管理、WebSphere ---相关内容整理_ejb jpa-CSDN博客

前言:


在 EJB(Enterprise JavaBeans) 中,事务管理也是一个核心功能。EJB 提供了类似于 Spring 的注解来控制事务行为。以下是 EJB 中常用的与事务管理相关的注解及其作用:

1. @TransactionManagement


作用:指定 EJB 的事务管理方式(容器管理或 Bean 管理)。

类全称:javax.ejb.TransactionManagement

属性:

value:可以是 TransactionManagementType.CONTAINER(容器管理事务,默认)或 TransactionManagementType.BEAN(Bean 管理事务)。
 

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyEJB {
    // 业务逻辑
}

===


2. @TransactionAttribute


作用:指定 EJB 方法的事务属性(类似于 Spring 的 @Transactional)。

类全称:javax.ejb.TransactionAttribute

属性:

value:指定事务传播行为,可以是以下枚举值:

TransactionAttributeType.REQUIRED:如果当前存在事务,则加入该事务;否则创建一个新事务。

TransactionAttributeType.REQUIRES_NEW:总是创建一个新事务,如果当前存在事务,则挂起当前事务。

TransactionAttributeType.SUPPORTS:如果当前存在事务,则加入该事务;否则以非事务方式执行。

TransactionAttributeType.NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。

TransactionAttributeType.MANDATORY:如果当前存在事务,则加入该事务;否则抛出异常。

TransactionAttributeType.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

@Stateless
public class MyEJB {

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void doSomething() {
        // 业务逻辑
    }
}

===

3. @ApplicationException


作用:指定某个异常是否触发事务回滚。

类全称:javax.ejb.ApplicationException

属性:

rollback:如果为 true,则当抛出该异常时触发事务回滚;默认为 false。

@ApplicationException(rollback = true)
public class MyException extends Exception {
    // 自定义异常
}

===

4. @EJB


作用:用于注入 EJB 实例。

类全称:javax.ejb.EJB

说明:虽然不直接用于事务管理,但在 EJB 中,事务通常是通过容器管理的,因此注入的 EJB 实例会继承容器的事务行为。

@Stateless
public class MyEJB {

    @EJB
    private AnotherEJB anotherEJB;

    public void doSomething() {
        anotherEJB.doSomethingElse();
    }
}

===

5. @Stateless 和 @Stateful


作用:定义 EJB 的类型(无状态或有状态)。

类全称:

javax.ejb.Stateless

javax.ejb.Stateful

说明:事务行为通常与 EJB 的类型相关。无状态 Bean(@Stateless)通常更适合容器管理事务。

@Stateless
public class MyStatelessEJB {
    // 业务逻辑
}

@Stateful
public class MyStatefulEJB {
    // 业务逻辑
}

====

6. @PostConstruct 和 @PreDestroy


作用:用于定义 Bean 的生命周期回调方法。

类全称:

javax.annotation.PostConstruct

javax.annotation.PreDestroy

说明:虽然不直接用于事务管理,但这些方法可以在事务开始前或结束后执行一些逻辑

@Stateless
public class MyEJB {

    @PostConstruct
    public void init() {
        // 初始化逻辑
    }

    @PreDestroy
    public void cleanup() {
        // 清理逻辑
    }
}

7.不使用容器管理事务时,可以使用 @Stateless 吗

在 EJB(Enterprise JavaBeans) 中,@Stateless 注解通常与 容器管理事务(Container-Managed Transactions, CMT) 一起使用,因为无状态 Bean(@Stateless)的设计初衷是让容器管理其生命周期和事务行为

然而,EJB 规范 也允许在 @Stateless Bean 中使用 Bean 管理事务(Bean-Managed Transactions, BMT),但这并不是推荐的做法。

1. @Stateless 与事务管理的关系


默认行为:@Stateless Bean 默认使用 容器管理事务(CMT),即事务由容器自动管理,开发者无需显式控制事务的开始、提交或回滚。

Bean 管理事务(BMT):如果显式指定为 Bean 管理事务(通过 @TransactionManagement(TransactionManagementType.BEAN)),则开发者需要手动管理事务(使用 UserTransaction)。

2. 使用 @Stateless 并启用 Bean 管理事务

虽然技术上可行,但在 @Stateless Bean 中使用 Bean 管理事务(BMT)并不推荐,原因如下:

无状态性:@Stateless Bean 是无状态的,容器可能会在方法调用之间重用 Bean 实例。如果手动管理事务,可能会导致事务状态不一致。

复杂性:手动管理事务会增加代码的复杂性,容易引入错误(如忘记提交或回滚事务)。

性能问题:手动管理事务可能会导致事务持续时间过长,影响性能。

3. 如何在 @Stateless 中使用 Bean 管理事务

如果确实需要在 @Stateless Bean 中使用 Bean 管理事务,可以按照以下步骤实现:

步骤 1:指定事务管理方式为 BEAN

使用 @TransactionManagement(TransactionManagementType.BEAN) 注解显式指定事务管理方式为 Bean 管理事务。


步骤 2:注入 UserTransaction

通过 @Resource 注解注入 UserTransaction 对象,用于手动控制事务。


步骤 3:手动管理事务

在方法中显式调用 UserTransaction 的 begin()、commit() 和 rollback() 方法。

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(TransactionManagementType.BEAN) // 指定为 Bean 管理事务
public class MyStatelessBean {

    @Resource
    private UserTransaction userTransaction; // 注入 UserTransaction

    public void doSomething() {
        try {
            // 开始事务
            userTransaction.begin();

            // 业务逻辑
            // ...

            // 提交事务
            userTransaction.commit();
        } catch (Exception e) {
            try {
                // 回滚事务
                userTransaction.rollback();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

4. 推荐做法


优先使用容器管理事务(CMT):对于 @Stateless Bean,推荐使用容器管理事务,因为容器可以更好地管理事务的生命周期,减少代码复杂性。

仅在必要时使用 Bean 管理事务(BMT):如果确实需要更细粒度的事务控制(例如跨多个方法的事务),可以考虑使用 @Stateful Bean 并启用 Bean 管理事务。

5. @Stateful 与 Bean 管理事务

如果需要在 Bean 中手动管理事务,通常更推荐使用 @Stateful Bean,因为有状态 Bean 可以更好地维护事务状态。

==

import javax.annotation.Resource;
import javax.ejb.Stateful;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;

@Stateful
@TransactionManagement(TransactionManagementType.BEAN) // 指定为 Bean 管理事务
public class MyStatefulBean {

    @Resource
    private UserTransaction userTransaction; // 注入 UserTransaction

    public void doSomething() {
        try {
            // 开始事务
            userTransaction.begin();

            // 业务逻辑
            // ...

            // 提交事务
            userTransaction.commit();
        } catch (Exception e) {
            try {
                // 回滚事务
                userTransaction.rollback();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

==

总结1


EJB 提供了 @TransactionManagement 和 @TransactionAttribute 等注解来控制事务行为。

事务管理方式可以是容器管理(默认)或 Bean 管理。

事务传播行为通过 TransactionAttributeType 枚举类来配置。

EJB 的事务管理与 Spring 的事务管理类似,但 EJB 更依赖于容器(如 Java EE 应用服务器)。

===

总结2

@Stateless Bean 可以使用 Bean 管理事务(BMT),但不推荐这样做,因为无状态 Bean 的设计初衷是让容器管理事务。

推荐使用容器管理事务(CMT),因为它更简单、更安全。

如果需要手动管理事务,建议使用 @Stateful Bean。


如果你有更多问题或需要进一步的帮助,请告诉我!


http://www.kler.cn/a/514573.html

相关文章:

  • 消息队列篇--原理篇--Pulsar和Kafka对比分析
  • windows平台intel-vpl编译
  • 【Maui】下拉框的实现,绑定键值对
  • npm操作大全:从入门到精通
  • MATLAB语言的文件操作
  • 基于AutoDL云计算平台+LLaMA-Factory训练平台微调本地大模型
  • Qt Creator 15.0.0如何更换主题和字体
  • 【Java】常用工具类方法:树形结构、获取IP、对象拷贝、File相关、雪花算法等
  • ubuntu 安装显卡驱动gpu-cuda
  • TiDB 对 Hadoop 的影响:大数据时代的新选择
  • 深入理解 Java 的并发容器
  • MongoDB部署模式
  • 《论文阅读》GPT-3是否会产生移情对话?一种新的情境示例选择方法和用于生成同理心对话的自动评估度量 ICCL 2022
  • 手机网络性能测试仪器介绍
  • c#配置config文件
  • 布局预览问题
  • 持续升级《在线写python》小程序的功能,文章页增加一键复制功能,并自动去掉html标签
  • Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类
  • 快速构建springboot+vue后台管理系统
  • 【C++学习篇】滑动窗口--结合例题讲解思路
  • FPGA自分频产生的时钟如何使用?
  • 风光并网对电网电能质量影响的matlab/simulink仿真建模
  • NLTK句法分析与依存解析
  • 强化学习-Q学习-Q表-Bellman方程式
  • 软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(5)
  • Scala语言的云计算