0
# HTTP Transaction Propagation
1
2
The HTTP transaction propagation capability provides automatic transaction context propagation across HTTP service calls in web applications. It supports both javax and Jakarta EE servlet environments, enabling distributed transactions to seamlessly flow between microservices.
3
4
## Installation and Setup
5
6
HTTP transaction propagation is enabled by default in web applications:
7
8
```properties
9
# Enable HTTP transaction context propagation (default: true)
10
seata.client.http.interceptor-enabled=true
11
12
# Additional HTTP configuration
13
seata.client.http.request-headers=TX_XID,TX_BRANCH_ID
14
seata.client.http.response-headers=TX_XID
15
```
16
17
## Core Components
18
19
### Web MVC Configurers
20
21
Automatic configuration of request interceptors for transaction context handling.
22
23
#### Jakarta EE Support
24
25
```java { .api }
26
@Bean
27
@ConditionalOnClass(name = "jakarta.servlet.http.HttpServletRequest")
28
public JakartaSeataWebMvcConfigurer jakartaSeataWebMvcConfigurer();
29
```
30
31
**Returns:** `JakartaSeataWebMvcConfigurer` - Web MVC configurer for Jakarta EE environments
32
33
#### Javax Servlet Support
34
35
```java { .api }
36
@Bean
37
@ConditionalOnMissingBean(JakartaSeataWebMvcConfigurer.class)
38
public SeataWebMvcConfigurer seataWebMvcConfigurer();
39
```
40
41
**Returns:** `SeataWebMvcConfigurer` - Web MVC configurer for javax servlet environments
42
43
## Automatic Transaction Context Propagation
44
45
### Incoming HTTP Requests
46
47
Transaction context is automatically extracted from incoming HTTP requests:
48
49
```java
50
@RestController
51
public class OrderController {
52
53
@Autowired
54
private OrderService orderService;
55
56
@PostMapping("/orders")
57
public ResponseEntity<Order> createOrder(@RequestBody Order order) {
58
// Transaction context is automatically available here
59
// if this request is part of a distributed transaction
60
61
Order createdOrder = orderService.createOrder(order);
62
return ResponseEntity.ok(createdOrder);
63
}
64
}
65
```
66
67
### Outgoing HTTP Requests
68
69
Transaction context is automatically propagated to outgoing HTTP requests:
70
71
```java
72
@Service
73
public class PaymentService {
74
75
@Autowired
76
private RestTemplate restTemplate;
77
78
@GlobalTransactional
79
public void processPayment(String orderId, BigDecimal amount) {
80
// Transaction context will be automatically added to HTTP headers
81
// when making calls to other services
82
83
PaymentRequest request = new PaymentRequest(orderId, amount);
84
85
// This call will include transaction headers automatically
86
PaymentResponse response = restTemplate.postForObject(
87
"http://payment-service/payments",
88
request,
89
PaymentResponse.class
90
);
91
}
92
}
93
```
94
95
## RestTemplate Integration
96
97
### Automatic Interceptor Registration
98
99
Seata automatically configures RestTemplate with transaction context interceptors:
100
101
```java
102
@Configuration
103
public class RestTemplateConfig {
104
105
@Bean
106
public RestTemplate restTemplate() {
107
RestTemplate restTemplate = new RestTemplate();
108
// Seata interceptors are automatically added
109
// No manual configuration required
110
return restTemplate;
111
}
112
}
113
```
114
115
### Manual RestTemplate Configuration
116
117
For custom RestTemplate configurations:
118
119
```java
120
@Configuration
121
public class CustomRestTemplateConfig {
122
123
@Bean
124
public RestTemplate customRestTemplate() {
125
RestTemplate restTemplate = new RestTemplate();
126
127
// Add custom interceptors
128
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
129
interceptors.add(new CustomInterceptor());
130
131
// Seata interceptors will be added automatically
132
restTemplate.setInterceptors(interceptors);
133
134
return restTemplate;
135
}
136
}
137
```
138
139
## WebClient Integration
140
141
For reactive applications using WebClient:
142
143
```java
144
@Configuration
145
public class WebClientConfig {
146
147
@Bean
148
public WebClient webClient() {
149
return WebClient.builder()
150
// Seata filters are automatically configured
151
.build();
152
}
153
}
154
```
155
156
```java
157
@Service
158
public class ReactivePaymentService {
159
160
@Autowired
161
private WebClient webClient;
162
163
@GlobalTransactional
164
public Mono<PaymentResponse> processPaymentAsync(String orderId, BigDecimal amount) {
165
PaymentRequest request = new PaymentRequest(orderId, amount);
166
167
return webClient.post()
168
.uri("http://payment-service/payments")
169
.bodyValue(request)
170
.retrieve()
171
.bodyToMono(PaymentResponse.class);
172
// Transaction context propagated automatically
173
}
174
}
175
```
176
177
## HTTP Headers for Transaction Context
178
179
### Standard Transaction Headers
180
181
Seata uses specific HTTP headers to propagate transaction context:
182
183
```java { .api }
184
// Request headers containing transaction context
185
public static final String TX_XID = "TX_XID"; // Global transaction ID
186
public static final String TX_BRANCH_ID = "TX_BRANCH_ID"; // Branch transaction ID
187
public static final String TX_APPLICATION_NAME = "TX_APPLICATION_NAME"; // Application identifier
188
public static final String TX_SERVICE_GROUP = "TX_SERVICE_GROUP"; // Service group name
189
```
190
191
### Custom Header Configuration
192
193
Configure additional headers for transaction propagation:
194
195
```properties
196
# Custom request headers to propagate
197
seata.client.http.request-headers=TX_XID,TX_BRANCH_ID,CUSTOM_HEADER
198
199
# Custom response headers to extract
200
seata.client.http.response-headers=TX_XID,TX_STATUS
201
```
202
203
## Auto-Configuration Details
204
205
HTTP transaction propagation is configured through `SeataHttpAutoConfiguration`:
206
207
```java { .api }
208
@Configuration(proxyBeanMethods = false)
209
@ConditionalOnWebApplication
210
@ConditionalOnMissingBean(SeataWebMvcConfigurer.class)
211
@ConditionalOnProperty(prefix = "seata.client.http", name = "interceptor-enabled", havingValue = "true", matchIfMissing = true)
212
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
213
public class SeataHttpAutoConfiguration {
214
215
@Bean
216
@ConditionalOnClass(name = "jakarta.servlet.http.HttpServletRequest")
217
public JakartaSeataWebMvcConfigurer jakartaSeataWebMvcConfigurer();
218
219
@Bean
220
@ConditionalOnMissingBean(JakartaSeataWebMvcConfigurer.class)
221
public SeataWebMvcConfigurer seataWebMvcConfigurer();
222
}
223
```
224
225
**Activation Conditions:**
226
- Web application context required
227
- `seata.client.http.interceptor-enabled=true` (default)
228
- Automatically detects Jakarta EE vs javax servlet environments
229
230
## Microservices Integration
231
232
### Service-to-Service Communication
233
234
Example of distributed transaction across multiple microservices:
235
236
```java
237
// Order Service
238
@Service
239
public class OrderService {
240
241
@Autowired
242
private PaymentServiceClient paymentClient;
243
244
@Autowired
245
private InventoryServiceClient inventoryClient;
246
247
@GlobalTransactional
248
public Order createOrder(Order order) {
249
// 1. Save order locally
250
Order savedOrder = orderRepository.save(order);
251
252
// 2. Call Payment Service (transaction context propagated)
253
PaymentResponse payment = paymentClient.processPayment(
254
order.getCustomerId(),
255
order.getTotalAmount()
256
);
257
258
// 3. Call Inventory Service (transaction context propagated)
259
InventoryResponse inventory = inventoryClient.reserveItems(
260
order.getItems()
261
);
262
263
// If any step fails, all services will rollback
264
return savedOrder;
265
}
266
}
267
```
268
269
```java
270
// Payment Service
271
@RestController
272
public class PaymentController {
273
274
@PostMapping("/payments")
275
public PaymentResponse processPayment(@RequestBody PaymentRequest request) {
276
// This method automatically participates in the distributed transaction
277
// initiated by the Order Service
278
279
return paymentService.processPayment(request);
280
}
281
}
282
```
283
284
### Feign Client Integration
285
286
For Spring Cloud Feign clients:
287
288
```java
289
@FeignClient(name = "payment-service")
290
public interface PaymentServiceClient {
291
292
@PostMapping("/payments")
293
PaymentResponse processPayment(@RequestBody PaymentRequest request);
294
// Transaction headers automatically added by Seata interceptors
295
}
296
```
297
298
## Gateway Integration
299
300
### Spring Cloud Gateway
301
302
For API Gateway scenarios:
303
304
```java
305
@Configuration
306
public class GatewayConfig {
307
308
@Bean
309
public GlobalFilter seataTransactionFilter() {
310
return (exchange, chain) -> {
311
// Transaction context is automatically handled
312
// for requests passing through the gateway
313
return chain.filter(exchange);
314
};
315
}
316
}
317
```
318
319
### Zuul Integration
320
321
For Zuul proxy configurations:
322
323
```java
324
@Component
325
public class SeataZuulFilter extends ZuulFilter {
326
327
@Override
328
public String filterType() {
329
return "pre";
330
}
331
332
@Override
333
public int filterOrder() {
334
return 1;
335
}
336
337
@Override
338
public boolean shouldFilter() {
339
return true;
340
}
341
342
@Override
343
public Object run() {
344
// Transaction context automatically propagated
345
// through Zuul proxy requests
346
return null;
347
}
348
}
349
```
350
351
## Error Handling and Timeout
352
353
### HTTP Client Timeout Configuration
354
355
Configure timeouts for HTTP calls within distributed transactions:
356
357
```properties
358
# RestTemplate timeout configuration
359
seata.client.http.connect-timeout=5000
360
seata.client.http.read-timeout=30000
361
362
# Circuit breaker integration
363
resilience4j.circuitbreaker.instances.payment-service.timeout-duration=PT30S
364
```
365
366
### Error Propagation
367
368
HTTP errors are automatically handled within the transaction context:
369
370
```java
371
@Service
372
public class OrderService {
373
374
@GlobalTransactional(rollbackFor = {HttpClientErrorException.class, HttpServerErrorException.class})
375
public Order createOrder(Order order) {
376
try {
377
// Service calls with automatic error handling
378
PaymentResponse payment = paymentClient.processPayment(order);
379
InventoryResponse inventory = inventoryClient.reserveItems(order);
380
381
return orderRepository.save(order);
382
383
} catch (HttpClientErrorException e) {
384
// 4xx errors trigger transaction rollback
385
log.error("Client error in distributed transaction", e);
386
throw e;
387
388
} catch (HttpServerErrorException e) {
389
// 5xx errors trigger transaction rollback
390
log.error("Server error in distributed transaction", e);
391
throw e;
392
}
393
}
394
}
395
```
396
397
## Security Integration
398
399
### Authentication Token Propagation
400
401
Combine transaction context with security tokens:
402
403
```java
404
@Configuration
405
public class SecurityConfig {
406
407
@Bean
408
public RestTemplate secureRestTemplate() {
409
RestTemplate restTemplate = new RestTemplate();
410
411
// Add custom interceptors for security
412
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
413
interceptors.add(new BearerTokenInterceptor());
414
415
// Seata transaction interceptors are added automatically
416
restTemplate.setInterceptors(interceptors);
417
418
return restTemplate;
419
}
420
}
421
```
422
423
### Custom Security Headers
424
425
Configure additional security headers alongside transaction headers:
426
427
```properties
428
# Include security headers with transaction context
429
seata.client.http.request-headers=TX_XID,TX_BRANCH_ID,Authorization,X-User-ID
430
```
431
432
## Performance and Monitoring
433
434
### HTTP Request Monitoring
435
436
Monitor transaction context propagation:
437
438
```properties
439
# Enable HTTP transaction logging
440
logging.level.io.seata.integration.http=DEBUG
441
442
# Monitor request/response headers
443
logging.level.org.springframework.web.client.RestTemplate=DEBUG
444
```
445
446
### Performance Optimization
447
448
```properties
449
# Connection pool optimization for HTTP clients
450
seata.client.http.max-connections=200
451
seata.client.http.max-connections-per-route=20
452
453
# Keep-alive configuration
454
seata.client.http.keep-alive-duration=PT60S
455
```
456
457
## Troubleshooting
458
459
### Common Issues
460
461
1. **Transaction Context Not Propagated**: Check interceptor configuration and web application context
462
2. **Header Missing**: Verify HTTP header configuration and client setup
463
3. **Timeout Issues**: Adjust HTTP client timeout settings
464
4. **Security Conflicts**: Ensure security interceptors don't interfere with transaction headers
465
466
### Debug Configuration
467
468
```properties
469
# Debug HTTP transaction propagation
470
logging.level.io.seata.integration.http=DEBUG
471
logging.level.io.seata.core.context=DEBUG
472
473
# Monitor HTTP headers
474
logging.level.org.springframework.web.servlet.mvc.method.annotation=DEBUG
475
```
476
477
### Testing Transaction Propagation
478
479
Verify transaction context propagation in tests:
480
481
```java
482
@SpringBootTest
483
@Transactional
484
public class TransactionPropagationTest {
485
486
@Test
487
public void testTransactionContextPropagation() {
488
// Start global transaction
489
String xid = GlobalTransactionContext.getCurrentOrCreate().getXid();
490
491
// Make HTTP call
492
ResponseEntity<String> response = restTemplate.getForEntity("/test", String.class);
493
494
// Verify transaction headers were sent
495
assertThat(response.getHeaders().get("TX_XID")).contains(xid);
496
}
497
}
498
```