@Override public void beginTransaction() { delegate.beginTransaction(); }
void beginTransaction() { if (!useTransactions) { return; } if (!transactionsInitialized) { producer.initTransactions(); transactionsInitialized = true; } producer.beginTransaction(); activeTransaction = true; }
void beginTransaction() { if (!useTransactions) { return; } if (!transactionsInitialized) { producer.initTransactions(); transactionsInitialized = true; } producer.beginTransaction(); activeTransaction = true; }
void beginTransaction() { if (!useTransactions) { return; } if (!transactionsInitialized) { producer.initTransactions(); transactionsInitialized = true; } producer.beginTransaction(); activeTransaction = true; }
producerTmp.beginTransaction();
@Test(expected = KafkaException.class) public void testOnlyCanExecuteCloseAfterInitTransactionsTimeout() { Map<String, Object> configs = new HashMap<>(); configs.put(ProducerConfig.TRANSACTIONAL_ID_CONFIG, "bad-transaction"); configs.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 5); configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9000"); Time time = new MockTime(); MetadataResponse initialUpdateResponse = TestUtils.metadataUpdateWith(1, singletonMap("topic", 1)); Metadata metadata = new Metadata(0, Long.MAX_VALUE, true); metadata.update(initialUpdateResponse, time.milliseconds()); MockClient client = new MockClient(time, metadata); Producer<String, String> producer = new KafkaProducer<>(configs, new StringSerializer(), new StringSerializer(), metadata, client, null, time); try { producer.initTransactions(); } catch (TimeoutException e) { // expected } // other transactional operations should not be allowed if we catch the error after initTransactions failed try { producer.beginTransaction(); } finally { producer.close(Duration.ofMillis(0)); } }
@Override public void beginTransaction() throws ProducerFencedException { if (logger.isDebugEnabled()) { logger.debug("beginTransaction: " + this); } try { this.delegate.beginTransaction(); } catch (RuntimeException e) { if (logger.isErrorEnabled()) { logger.error("beginTransaction failed: " + this, e); } this.txFailed = true; throw e; } }
/** * Obtain a Producer that is synchronized with the current transaction, if any. * @param producerFactory the ProducerFactory to obtain a Channel for * @param <K> the key type. * @param <V> the value type. * @return the resource holder. */ public static <K, V> KafkaResourceHolder<K, V> getTransactionalResourceHolder( final ProducerFactory<K, V> producerFactory) { Assert.notNull(producerFactory, "ProducerFactory must not be null"); @SuppressWarnings("unchecked") KafkaResourceHolder<K, V> resourceHolder = (KafkaResourceHolder<K, V>) TransactionSynchronizationManager .getResource(producerFactory); if (resourceHolder == null) { Producer<K, V> producer = producerFactory.createProducer(); try { producer.beginTransaction(); } catch (RuntimeException e) { producer.close(); throw e; } resourceHolder = new KafkaResourceHolder<K, V>(producer); bindResourceToTransaction(resourceHolder, producerFactory); } return resourceHolder; }
@SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testDeclarative() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DeclarativeConfig.class); Tx1 tx1 = ctx.getBean(Tx1.class); tx1.txMethod(); ProducerFactory producerFactory = ctx.getBean(ProducerFactory.class); verify(producerFactory, times(2)).createProducer(); Producer producer1 = ctx.getBean("producer1", Producer.class); Producer producer2 = ctx.getBean("producer1", Producer.class); InOrder inOrder = inOrder(producer1, producer2); inOrder.verify(producer1).beginTransaction(); inOrder.verify(producer1).send(eq(new ProducerRecord("foo", "bar")), any(Callback.class)); inOrder.verify(producer1).send(eq(new ProducerRecord("baz", "qux")), any(Callback.class)); inOrder.verify(producer2).beginTransaction(); inOrder.verify(producer2).send(eq(new ProducerRecord("fiz", "buz")), any(Callback.class)); inOrder.verify(producer2).commitTransaction(); inOrder.verify(producer1).commitTransaction(); ctx.close(); }
@SuppressWarnings("unchecked") @Test public void discardRemainingRecordsFromPollAndSeek() throws Exception { assertThat(this.config.deliveryLatch.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(this.config.pollLatch.await(10, TimeUnit.SECONDS)).isTrue(); this.registry.stop(); assertThat(this.config.closeLatch.await(10, TimeUnit.SECONDS)).isTrue(); InOrder inOrder = inOrder(this.consumer, this.producer); inOrder.verify(this.consumer).subscribe(any(Collection.class), any(ConsumerRebalanceListener.class)); inOrder.verify(this.consumer).poll(Duration.ofMillis(ContainerProperties.DEFAULT_POLL_TIMEOUT)); inOrder.verify(this.producer).beginTransaction(); inOrder.verify(this.consumer).seek(new TopicPartition("foo", 0), 0L); inOrder.verify(this.consumer).seek(new TopicPartition("foo", 1), 0L); inOrder.verify(this.consumer).seek(new TopicPartition("foo", 2), 0L); inOrder.verify(this.producer).abortTransaction(); inOrder.verify(this.consumer).poll(Duration.ofMillis(ContainerProperties.DEFAULT_POLL_TIMEOUT)); inOrder.verify(this.producer).beginTransaction(); Map<TopicPartition, OffsetAndMetadata> offsets = new LinkedHashMap<>(); offsets.put(new TopicPartition("foo", 0), new OffsetAndMetadata(2L)); offsets.put(new TopicPartition("foo", 1), new OffsetAndMetadata(2L)); offsets.put(new TopicPartition("foo", 2), new OffsetAndMetadata(2L)); inOrder.verify(this.producer).sendOffsetsToTransaction(offsets, CONTAINER_ID); inOrder.verify(this.producer).commitTransaction(); assertThat(this.config.ehException).isInstanceOf(ListenerExecutionFailedException.class); assertThat(((ListenerExecutionFailedException) this.config.ehException).getGroupId()).isEqualTo(CONTAINER_ID); }
inOrder.verify(this.consumer).subscribe(any(Collection.class), any(ConsumerRebalanceListener.class)); inOrder.verify(this.consumer).poll(Duration.ofMillis(ContainerProperties.DEFAULT_POLL_TIMEOUT)); inOrder.verify(this.producer).beginTransaction(); Map<TopicPartition, OffsetAndMetadata> offsets = new LinkedHashMap<>(); offsets.put(new TopicPartition("foo", 0), new OffsetAndMetadata(1L));
inOrder.verify(this.consumer).subscribe(any(Collection.class), any(ConsumerRebalanceListener.class)); inOrder.verify(this.consumer).poll(Duration.ofMillis(ContainerProperties.DEFAULT_POLL_TIMEOUT)); inOrder.verify(this.producer).beginTransaction(); Map<TopicPartition, OffsetAndMetadata> offsets = new LinkedHashMap<>(); offsets.put(new TopicPartition("foo", 0), new OffsetAndMetadata(1L));
@Test public void testDeadLetterPublisherWhileTransactionActive() { @SuppressWarnings("unchecked") Producer<Object, Object> producer1 = mock(Producer.class); @SuppressWarnings("unchecked") Producer<Object, Object> producer2 = mock(Producer.class); producer1.initTransactions(); @SuppressWarnings("unchecked") ProducerFactory<Object, Object> pf = mock(ProducerFactory.class); given(pf.transactionCapable()).willReturn(true); given(pf.createProducer()).willReturn(producer1).willReturn(producer2); KafkaTemplate<Object, Object> template = spy(new KafkaTemplate<>(pf)); template.setDefaultTopic(STRING_KEY_TOPIC); KafkaTransactionManager<Object, Object> tm = new KafkaTransactionManager<>(pf); new TransactionTemplate(tm).execute(s -> { new DeadLetterPublishingRecoverer(template).accept( new ConsumerRecord<>(STRING_KEY_TOPIC, 0, 0L, "key", "foo"), new RuntimeException("foo")); return null; }); verify(producer1).beginTransaction(); verify(producer1).commitTransaction(); verify(producer1).close(); verify(producer2, never()).beginTransaction(); verify(template, never()).executeInTransaction(any()); }
}).given(producer).beginTransaction(); inOrder.verify(producer).beginTransaction(); inOrder.verify(producer).send(any(), any()); inOrder.verify(producer).commitTransaction(); inOrder.verify(producer).beginTransaction(); inOrder.verify(producer).close(); inOrder.verifyNoMoreInteractions();
inOrder.verify(producer1).beginTransaction(); inOrder.verify(producer2).beginTransaction(); inOrder.verify(producer2).commitTransaction(); inOrder.verify(producer2).close();
assertThat(closeLatch.await(10, TimeUnit.SECONDS)).isTrue(); InOrder inOrder = inOrder(producer); inOrder.verify(producer).beginTransaction(); inOrder.verify(producer).sendOffsetsToTransaction(Collections.singletonMap(topicPartition, new OffsetAndMetadata(0)), "group"); inOrder.verify(producer).commitTransaction(); inOrder.verify(producer).close(); inOrder.verify(producer).beginTransaction(); ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class); inOrder.verify(producer).send(captor.capture(), any(Callback.class));
assertThat(seekLatch.await(10, TimeUnit.SECONDS)).isTrue(); InOrder inOrder = inOrder(producer); inOrder.verify(producer).beginTransaction(); ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class); verify(producer).send(captor.capture(), any(Callback.class));
assertThat(seekLatch.await(10, TimeUnit.SECONDS)).isTrue(); InOrder inOrder = inOrder(producer); inOrder.verify(producer).beginTransaction(); ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class); verify(producer).send(captor.capture(), any(Callback.class));
inOrder.verify(producer).beginTransaction(); ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class); inOrder.verify(producer).send(captor.capture(), any(Callback.class));