Menerapkan Produsen Transaksional
Konfigurasikan dan gunakan produsen transaksional di Spring Boot untuk memastikan bahwa sekumpulan pesan berhasil dikirim seluruhnya atau tidak sama sekali.
Menerapkan Produsen Transaksional adalah pelajaran Advanced Spring Boot 4: Event-Driven Architecture (Kafka) gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Advanced Spring Boot 4: Event-Driven Architecture (Kafka), dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Advanced Spring Boot 4: Event-Driven Architecture (Kafka) mencakup 4 pelajaran total.
Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.
Atomic Operations with Kafka
In distributed systems, ensuring that a series of operations either all succeed or all fail (atomicity) is crucial. This is where transactional producers in Kafka come in.
They allow you to send multiple messages to different topics and partitions as a single atomic unit. If any part of the transaction fails, all messages sent within that transaction are rolled back.
Identifying Your Transaction
To use transactional producers, you must configure a unique transactional.id for your producer. This ID is essential for Kafka to guarantee exactly-once semantics and recover transactions across producer restarts.
Think of it as a unique name for your producer's transactional session. Kafka uses it to identify the producer and its ongoing transactions.
Spring Boot Configuration
First, ensure you have the spring-kafka dependency. Then, configure your Kafka broker address and the transactional-id-prefix in application.yml. This prefix will be used to generate unique IDs for each producer instance.
# application.yml
spring:
kafka:
bootstrap-servers: localhost:9092
producer:
# A unique ID prefix for the transactional producer
transactional-id-prefix: my-app-tx-Configuring Transactional Producer
Spring Kafka simplifies transactional producer setup. You need to configure your ProducerFactory to be transactional and then create a KafkaTemplate using it.
Notice acks: all is crucial for transactions, ensuring all in-sync replicas acknowledge the message before it's considered committed.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import java.util.HashMap;
import java.util.Map;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.springframework.beans.factory.annotation.Value;
@Configuration
public class KafkaProducerConfig {
@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;
@Value("${spring.kafka.producer.transactional-id-prefix}")
private String transactionalIdPrefix;
@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringSerializer.class);
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringSerializer.class);
configProps.put(ProducerConfig.ACKS_CONFIG, "all"); // Essential for transactions
configProps.put(ProducerConfig.RETRIES_CONFIG, 0); // Kafka handles retries internally for transactions
DefaultKafkaProducerFactory<String, String> factory = new DefaultKafkaProducerFactory<>(configProps);
factory.setTransactionIdPrefix(transactionalIdPrefix); // Set the transactional ID prefix
return factory;
}
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}Integrating with Spring Transactions
To integrate Kafka transactions with Spring's declarative transaction management (@Transactional), you need to define a KafkaTransactionManager bean.
This manager coordinates the Kafka producer transactions with other Spring-managed transactions (e.g., database operations), allowing you to achieve atomicity across different resource types.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.transaction.KafkaTransactionManager;
import org.springframework.kafka.core.ProducerFactory;
@Configuration
public class KafkaTransactionManagerConfig {
@Bean
public KafkaTransactionManager kafkaTransactionManager(ProducerFactory<String, String> producerFactory) {
return new KafkaTransactionManager(producerFactory);
}
}Sending a Single Transactional Message
Now you can use @Transactional on a service method. Any Kafka messages sent within this method using the configured KafkaTemplate will be part of a single transaction.
If the method completes successfully, the transaction is committed. If an exception occurs, it's rolled back and no messages are sent.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Service
public class TransactionalProducerService {
private final KafkaTemplate<String, String> kafkaTemplate;
@Autowired
public TransactionalProducerService(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
@Transactional
public void sendGreeting(String user) {
String message = "Hello, " + user + "!";
kafkaTemplate.send("greetings-topic", user, message);
System.out.println("Attempted to send: " + message);
}
// Main method for a runnable Spring Boot application
@SpringBootApplication
public static class DemoApplication {
public static void main(String[] args) {
// This would typically be run as a Spring Boot application
// and the service called via a controller or runner.
// For demonstration, we just show the structure.
System.out.println("Run this as a Spring Boot app to use the service.");
// SpringApplication.run(DemoApplication.class, args);
}
}
}Multiple Messages, One Transaction
The real power of transactional producers shines when sending multiple messages. All messages within the @Transactional method are grouped.
If one send fails, all previously sent messages within that transaction are aborted. This ensures data consistency across different topics or partitions.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderProcessingService {
private final KafkaTemplate<String, String> kafkaTemplate;
@Autowired
public OrderProcessingService(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
@Transactional
public void processOrder(String orderId, String item) {
// Send order creation event
kafkaTemplate.send("order-created-topic", orderId, "Order " + orderId + " created for " + item);
System.out.println("Sent order creation for: " + orderId);
// Simulate a failure for demonstration
if (orderId.equals("FAIL_ORDER")) {
throw new RuntimeException("Simulated order processing failure!");
}
// Send inventory update event
kafkaTemplate.send("inventory-update-topic", item, "Item " + item + " quantity reduced for order " + orderId);
System.out.println("Sent inventory update for: " + item);
System.out.println("Order " + orderId + " processed transactionally.");
}
// Main method for a runnable Spring Boot application
public static void main(String[] args) {
// This would typically be run as a Spring Boot application
// and the service called via a controller or runner.
System.out.println("Run this as a Spring Boot app to use the service.");
}
}Transaction Rollback Behavior
If an exception is thrown within a @Transactional method, the KafkaTransactionManager will initiate a transaction rollback.
This means any messages sent to Kafka within that transaction will not be visible to consumers. Kafka's transactional capabilities ensure that partial data is never committed, maintaining data integrity.
Why Atomicity Matters
Transactional producers are crucial for maintaining data integrity in complex event-driven workflows. They prevent scenarios where, for example, an order creation event is sent but the corresponding inventory update fails.
This guarantees that your system's state remains consistent, even in the face of transient errors or application crashes during processing.
Transactional Producer Check
Consider a Spring Boot application sending messages to Kafka using KafkaTemplate within a @Transactional method.
If an unchecked exception occurs after sending the first of two messages, what happens?
Recap: Atomic Messaging
We've learned how to implement transactional producers in Spring Boot Kafka. This involves configuring a transactional.id, enabling transactions in ProducerFactory, using KafkaTransactionManager, and marking service methods with @Transactional.
Transactional producers ensure atomicity, meaning a batch of messages either all commit or all roll back, vital for data consistency. Next, we'll explore achieving exactly-once processing semantics by combining transactional producers with idempotent consumers.
Belajar Advanced Spring Boot 4: Event-Driven Architecture (Kafka) dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 12
- Pelajaran
- 48
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Menerapkan Produsen Transaksional” gratis?
Ya — teks lengkap “Menerapkan Produsen Transaksional” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Advanced Spring Boot 4: Event-Driven Architecture (Kafka), upgrade ke CoddyKit PRO. Kursus Advanced Spring Boot 4: Event-Driven Architecture (Kafka) mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Menerapkan Produsen Transaksional”?
Konfigurasikan dan gunakan produsen transaksional di Spring Boot untuk memastikan bahwa sekumpulan pesan berhasil dikirim seluruhnya atau tidak sama sekali. Kamu berlatih Advanced Spring Boot 4: Event-Driven Architecture (Kafka) dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Advanced Spring Boot 4: Event-Driven Architecture (Kafka)?
Tidak diperlukan pengalaman sebelumnya. Advanced Spring Boot 4: Event-Driven Architecture (Kafka) di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Menerapkan Produsen Transaksional” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Advanced Spring Boot 4: Event-Driven Architecture (Kafka) ini?
Ya. Setiap pelajaran Advanced Spring Boot 4: Event-Driven Architecture (Kafka) menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Memahami Transaksi Kafka
- Menerapkan Produsen Transaksional
- Semantik Pemrosesan Tepat Satu Kali
- Pola Outbox Transaksional