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