Как настроить источник данных Oracle XA в приложении весенней загрузки, которое взаимодействует с EJB в JBoss EAP - PullRequest
0 голосов
/ 30 октября 2019

Я пытаюсь использовать EJB в загрузочном приложении Spring. Это приложение работает в 'undertow' и может вызывать EJB на JBoss EAP (Jboss EAP 7.0).

Я попытался настроить приложение для использования транзакций Oracle XA, но безуспешно.

Что мне нужно, так это то, что когда загрузочное приложение Spring вызывает EJB, и после вызова в этом приложении происходит сбой, когда EJB выполняет откат предыдущей работы.

Придерживается некоторых конфигурацийприложение весенней загрузки:

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 производится следующим образом: stuff

Контроллер весенней загрузки приложения

class AppControler {

    @AutoWired
    Service service

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

Служба весенней загрузки приложения

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
        }
}

реализация EJBкласс в JBoss EAP имеет вид


class EJBRemoteImpl implements EJBRemote {

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

Так что, когда возникает ошибка в 'dao.saveOtherThing ();'операция, выполненная в 'EJBRemove.saveSomeThing ();'требуется откат.

Если я поместил '@TransactionAttribute (TransactionAttributeType.MANDATORY)' в EJB, эта ошибка возникает:

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 происходит нормально, но отката не происходит.

...