【问题标题】:How to configure Oracle XA Datasource on spring boot app that communicating with an EJB in JBoss EAP如何在 Spring Boot 应用程序上配置与 JBoss EAP 中的 EJB 通信的 Oracle XA 数据源
【发布时间】:2019-10-30 17:16:55
【问题描述】:

我正在尝试在 Spring 引导应用程序上使用 EJB。此应用程序在“undertow”中运行,它可以调用 JBoss EAP (Jboss EAP 7.0) 上的 EJB。

我尝试将应用程序配置为使用 Oracle XA 事务但没有成功。

我需要的是,当 Spring boot 应用程序调用 EJB 时,调用后,此应用程序发生一些故障,EJB 回滚之前的工作。

遵循spring boot app的一些配置:

pom

<dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <dependency>
            <groupId>org.wildfly</groupId>
            <artifactId>wildfly-ejb-client-bom</artifactId>
            <version>17.0.0.Final</version>
            <type>pom</type>
        </dependency>

    </dependencies>

属性

spring.datasource.url=jdbc:oracle:thin:@<host>:<port>:<data>
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.xa.data-source-class-name=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
spring.datasource.xa.properties.driver-class-name=oracle.jdbc.driver.OracleDriver


spring.jpa.properties.hibernate.hbm2ddl.schema_filter_provider=<class>
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=true

spring.jpa.properties.hibernate.integration.envers.enabled=false

应用类

Configuration
@SpringBootApplication
@EnableTransactionManagement
@ComponentScan(basePackages={...,...})
@EntityScan(basePackages={...,...,...})
public class SpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication .class, args);
    }

EJB '生产者'


@Configuration
public class EJBConfiguration {

    @Bean
    public Context context() throws NamingException {
        Properties jndiProps = new Properties();
        jndiProps.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
        jndiProps.put("jboss.naming.client.ejb.context", true);
        jndiProps.put("java.naming.provider.url", "http-remoting://localhost:8081");
        return new InitialContext(jndiProps);
    }


@Bean
    public EJBRemote(Context c) throws NamingException {

        return (EJBRemote) c.lookup("full EJB remote name")
}

}

EJB 的调用如下: 东西

Spring Boot 应用控制器

class AppControler {

    @AutoWired
    Service service

    @PostMapping("/")
    @Transactional
    public ResponseEntity controllerMethod() {
        return new ResponseEntity<>(this.service.doStuff(), HttpStatus.OK);
    }
}

Spring Boot 应用服务

class Service {

        @Autowired
    private EJBRemote EJBRemote;

        @Autowired
    private DAOObject dao;

    @TransactionAttribute(TransactionAttributeType.MANDATORY)
        Public Object doStuff() {
             dao.save();
             EJBRemote.saveSomeThing(); // OK operation, needs to rolback if oerros occurs after
             dao.saveOtherThing();// errors occurs
        }
}

JBoss EAP 上的 EJB 实现类是这样的


class EJBRemoteImpl implements EJBRemote {

    @Override
    public void saveSomeThing() {
          someDao.save();
    }
}

所以当 'dao.saveOtherThing();' 发生错误时'EJBRemove.saveSomeThing();' 中的操作需要回滚。

如果我在 EJB 上放置“@TransactionAttribute(TransactionAttributeType.MANDATORY)”,则会出现此错误:

javax.ejb.EJBTransactionRequiredException: WFLYEJB0062: A transaction is required to call org.jboss.invocation.InterceptorContext@493c9dbb  
at org.jboss.as.ejb3.tx.CMTTxInterceptor.mandatory(CMTTxInterceptor.java:289) ~[na:na]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:233) ~[na:na]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
    at org.jboss.as.ejb3.remote.EJBRemoteTransactionPropagatingInterceptor.processInvocation(EJBRemoteTransactionPropagatingInterceptor.java:79) ~[na:na]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) ~[na:na]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
    at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) ~[na:na]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
.
.
.

如果注释 (@TransactionAttribute(TransactionAttributeType.MANDATORY)) 不存在,则对 EJB 的调用正常发生,但不会发生回滚。

【问题讨论】:

    标签: spring-boot jboss ejb integration xa


    【解决方案1】:

    您正在尝试在 Spring 服务中创建 EJB 事务,如果您想这样做,您需要将您的服务转换为 EJB,因此如果您希望此方法与 Spring 事务一起使用,所有操作将自动为TransactionAttribute.REQUIRED ,你需要使用来自Spring(org.springframework.transaction.annotation.Transactional)的@Transactional(propagation = Propagation.MANDATORY),但我不知道Spring事务是否在分布式上下文中工作,但你可以尝试。如果不将 Bean 转换为 EJB 将起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 2017-12-18
      • 2018-11-19
      • 2019-01-16
      • 2015-02-19
      • 1970-01-01
      • 2020-02-12
      相关资源
      最近更新 更多