I have a question, I have to use Atomikos with Axon framework, in Spring-Boot (without Axon Server). I am using Oracle DB, and I am using multiple threads (10) to send a lot of commands, and before that I am configuring an JtaTransactionManager for myself, but in some threads I get this kind of exception: javax.transaction.xa.XAException, raised -6 or -4 or -3 or ORA-02056: 2PC: k2lcom: bad two-phase command number rdonly from coord:. As I debugged I saw that the CommandGateWay is using JtaTransactionManager too. Is it right? When is this opening a transaction? Is that possible that my JtaTransactionManager and Axon's is in conflict? Did anybody had this kind of exceptions?
Sample code:
@Service
public class CreateEntitiesServiceImpl extends FutureCompleter implements CreateEntitiesService {
private static Logger logger = LoggerHelper.getDeveloperLogger(CreateEntitiesServiceImpl.class);
private final CommandGateway commandGateway;
private final ExecutionUtil executionUtil;
private final MyEntityRepository myEntityRepository;
public CreateEntitiesServiceImpl(CommandGateway commandGateway, ExecutionUtil executionUtil, MyEntityRepository myEntityRepository) {
this.commandGateway = commandGateway;
this.executionUtil = executionUtil;
this.myEntityRepository = myEntityRepository;
}
@Override
public void process(Message message) {
logger.info("Entity addition started!");
generateEntities();
logger.info("Entity addition finished!");
}
private void generateEntities() {
ExecutorService executorService = executionUtil.createExecutor(10, "createEntities");
List<Integer> list = IntStream.rangeClosed(1, 1000).boxed().collect(Collectors.toList());
CreateEntitiesService proxy = applicationContext.getBean(CreateEntitiesServiceImpl.class);
List<CompletableFuture<Void>> processingFutures = list.stream().map(
e -> CompletableFuture.runAsync(proxy::createEntity, executorService).whenComplete((x, y) -> executorService.shutdown()))
.collect(Collectors.toList());
processingFutures.stream().map(this::getVoidFuture).collect(Collectors.toList());
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createEntity() {
try {
MyEntity myEntity = new MyEntity();
myEntity.setEntityStringProperty("string");
myEntity.setEntityTimestampProperty(LocalDateTime.now());
MyEntity savedEntity = myEntityRepository.save(myEntity);
CreateAggregateCommand command = new CreateAggregateCommand(savedEntity.getEntityId(), savedEntity.getEntityStringProperty(),
savedEntity.getEntityTimestampProperty());
commandGateway.send(command);
} catch (Exception e) {
throw new CreateEntitiesException(e.getMessage(), e);
}
}
}
Thanks