|
72 | 72 | import org.springframework.kafka.test.context.EmbeddedKafka; |
73 | 73 | import org.springframework.kafka.test.utils.KafkaTestUtils; |
74 | 74 | import org.springframework.kafka.transaction.KafkaTransactionManager; |
| 75 | +import org.springframework.transaction.TransactionDefinition; |
| 76 | +import org.springframework.transaction.TransactionException; |
75 | 77 | import org.springframework.transaction.annotation.EnableTransactionManagement; |
76 | 78 | import org.springframework.transaction.annotation.Propagation; |
77 | 79 | import org.springframework.transaction.annotation.Transactional; |
78 | 80 | import org.springframework.transaction.support.AbstractPlatformTransactionManager; |
| 81 | +import org.springframework.transaction.support.DefaultTransactionStatus; |
79 | 82 | import org.springframework.transaction.support.TransactionTemplate; |
80 | 83 | import org.springframework.util.concurrent.SettableListenableFuture; |
81 | 84 |
|
@@ -296,14 +299,15 @@ public void testTransactionSynchronizationExceptionOnCommit() { |
296 | 299 |
|
297 | 300 | ResourcelessTransactionManager tm = new ResourcelessTransactionManager(); |
298 | 301 |
|
299 | | - new TransactionTemplate(tm) |
300 | | - .execute(s -> { |
301 | | - template.sendDefault("foo", "bar"); |
| 302 | + assertThatExceptionOfType(ProducerFencedException.class).isThrownBy(() -> |
| 303 | + new TransactionTemplate(tm) |
| 304 | + .execute(s -> { |
| 305 | + template.sendDefault("foo", "bar"); |
302 | 306 |
|
303 | | - // Mark the mock producer as fenced so it throws when committing the transaction |
304 | | - producer.fenceProducer(); |
305 | | - return null; |
306 | | - }); |
| 307 | + // Mark the mock producer as fenced so it throws when committing the transaction |
| 308 | + producer.fenceProducer(); |
| 309 | + return null; |
| 310 | + })); |
307 | 311 |
|
308 | 312 | assertThat(producer.transactionCommitted()).isFalse(); |
309 | 313 | assertThat(producer.closed()).isTrue(); |
@@ -573,6 +577,28 @@ void testNonTxWithTx() { |
573 | 577 | pf.destroy(); |
574 | 578 | } |
575 | 579 |
|
| 580 | + @Test |
| 581 | + void syncCommitFails() { |
| 582 | + DummyTM tm = new DummyTM(); |
| 583 | + MockProducer<String, String> producer = |
| 584 | + new MockProducer<>(true, new StringSerializer(), new StringSerializer()); |
| 585 | + producer.initTransactions(); |
| 586 | + producer.commitTransactionException = new IllegalStateException(); |
| 587 | + |
| 588 | + @SuppressWarnings("unchecked") |
| 589 | + ProducerFactory<String, String> pf = mock(ProducerFactory.class); |
| 590 | + given(pf.transactionCapable()).willReturn(true); |
| 591 | + given(pf.createProducer(isNull())).willReturn(producer); |
| 592 | + |
| 593 | + KafkaTemplate<String, String> template = new KafkaTemplate<>(pf); |
| 594 | + template.setDefaultTopic(STRING_KEY_TOPIC); |
| 595 | + |
| 596 | + assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> |
| 597 | + new TransactionTemplate(tm).execute(status -> template.sendDefault("foo"))); |
| 598 | + |
| 599 | + assertThat(tm.committed).isTrue(); |
| 600 | + } |
| 601 | + |
576 | 602 | @Configuration |
577 | 603 | @EnableTransactionManagement |
578 | 604 | public static class DeclarativeConfig { |
@@ -680,4 +706,29 @@ public void anotherTxMethod() { |
680 | 706 |
|
681 | 707 | } |
682 | 708 |
|
| 709 | + @SuppressWarnings("serial") |
| 710 | + private static final class DummyTM extends AbstractPlatformTransactionManager { |
| 711 | + |
| 712 | + boolean committed; |
| 713 | + |
| 714 | + @Override |
| 715 | + protected Object doGetTransaction() throws TransactionException { |
| 716 | + return new Object(); |
| 717 | + } |
| 718 | + |
| 719 | + @Override |
| 720 | + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { |
| 721 | + } |
| 722 | + |
| 723 | + @Override |
| 724 | + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { |
| 725 | + this.committed = true; |
| 726 | + } |
| 727 | + |
| 728 | + @Override |
| 729 | + protected void doRollback(DefaultTransactionStatus status) throws TransactionException { |
| 730 | + } |
| 731 | + |
| 732 | + } |
| 733 | + |
683 | 734 | } |
0 commit comments