0
# DataSource Auto-Proxying
1
2
The DataSource auto-proxying capability automatically wraps Spring DataSource beans with Seata transaction proxies, enabling transparent distributed transaction management for AT (Automatic Transaction) and XA modes. This eliminates the need for manual DataSource proxy configuration.
3
4
## Installation and Setup
5
6
Auto-proxying is enabled by default when DataSource beans are present:
7
8
```properties
9
# Enable DataSource auto-proxying (default: true)
10
seata.enable-auto-data-source-proxy=true
11
12
# Set proxy mode: AT (default) or XA
13
seata.data-source-proxy-mode=AT
14
15
# Use JDK dynamic proxy instead of CGLIB (default: false)
16
seata.use-jdk-proxy=false
17
```
18
19
## Core Components
20
21
### SeataAutoDataSourceProxyCreator Bean
22
23
The main component that creates DataSource proxies automatically.
24
25
```java { .api }
26
@Bean("seataAutoDataSourceProxyCreator")
27
public static SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator(
28
SeataProperties seataProperties
29
);
30
```
31
32
**Parameters:**
33
- `seataProperties`: Main Seata configuration properties containing proxy settings
34
35
**Returns:** `SeataAutoDataSourceProxyCreator` - Proxy creator that wraps DataSource beans
36
37
## Automatic DataSource Wrapping
38
39
### Basic DataSource Configuration
40
41
Your existing DataSource beans are automatically wrapped:
42
43
```java
44
@Configuration
45
public class DataSourceConfig {
46
47
@Bean
48
@Primary
49
public DataSource primaryDataSource() {
50
HikariConfig config = new HikariConfig();
51
config.setJdbcUrl("jdbc:mysql://localhost:3306/order_db");
52
config.setUsername("user");
53
config.setPassword("password");
54
return new HikariDataSource(config);
55
}
56
57
@Bean("inventoryDataSource")
58
public DataSource inventoryDataSource() {
59
HikariConfig config = new HikariConfig();
60
config.setJdbcUrl("jdbc:mysql://localhost:3306/inventory_db");
61
config.setUsername("user");
62
config.setPassword("password");
63
return new HikariDataSource(config);
64
}
65
66
// Both DataSources will be automatically proxied by Seata
67
// No additional configuration required
68
}
69
```
70
71
### Multiple DataSource Support
72
73
All DataSource beans in the application context are automatically proxied:
74
75
```java
76
@Service
77
public class OrderService {
78
79
@Autowired
80
@Qualifier("primaryDataSource")
81
private DataSource orderDataSource;
82
83
@Autowired
84
@Qualifier("inventoryDataSource")
85
private DataSource inventoryDataSource;
86
87
@GlobalTransactional
88
public void processOrder() {
89
// Both DataSources participate in the same distributed transaction
90
try (Connection orderConn = orderDataSource.getConnection();
91
Connection inventoryConn = inventoryDataSource.getConnection()) {
92
93
// Operations on both connections are coordinated
94
insertOrder(orderConn);
95
updateInventory(inventoryConn);
96
97
// If either operation fails, both will be rolled back
98
}
99
}
100
}
101
```
102
103
## Transaction Modes
104
105
### AT (Automatic Transaction) Mode
106
107
The default mode that provides automatic transaction management through SQL interception:
108
109
```properties
110
# AT mode configuration (default)
111
seata.data-source-proxy-mode=AT
112
113
# AT mode automatically handles:
114
# - SQL interception and modification
115
# - Undo log generation for rollback
116
# - Lock management for isolation
117
```
118
119
**Benefits:**
120
- Zero business logic intrusion
121
- Automatic rollback through undo logs
122
- High performance for most scenarios
123
124
**Requirements:**
125
- Primary key required for all tables
126
- Undo log table (`undo_log`) must exist
127
128
### XA Mode
129
130
Standards-based XA protocol support for strict ACID compliance:
131
132
```properties
133
# XA mode configuration
134
seata.data-source-proxy-mode=XA
135
136
# XA mode provides:
137
# - Standards-based two-phase commit
138
# - Strong consistency guarantees
139
# - Database-level transaction coordination
140
```
141
142
**Benefits:**
143
- Industry standard XA protocol
144
- Strong consistency guarantees
145
- No undo log requirements
146
147
**Requirements:**
148
- Database must support XA transactions
149
- Higher resource consumption
150
- Potential performance impact
151
152
## Configuration Properties
153
154
### DataSource Proxy Configuration
155
156
```java { .api }
157
public class SeataProperties {
158
// Enable automatic DataSource proxying
159
private boolean enableAutoDataSourceProxy = true;
160
161
// DataSource proxy mode: AT or XA
162
private String dataSourceProxyMode = "AT";
163
164
// Use JDK dynamic proxy instead of CGLIB
165
private boolean useJdkProxy = false;
166
167
// DataSource bean names to exclude from proxying
168
private String[] excludesForAutoProxying = {};
169
}
170
```
171
172
### Exclusions Configuration
173
174
Exclude specific DataSource beans from automatic proxying:
175
176
```properties
177
# Exclude specific DataSource beans by name
178
seata.excludes-for-auto-proxying=testDataSource,cacheDataSource
179
```
180
181
```java
182
@Configuration
183
public class DataSourceConfig {
184
185
@Bean
186
@Primary
187
public DataSource primaryDataSource() {
188
// This will be automatically proxied
189
return new HikariDataSource();
190
}
191
192
@Bean("testDataSource")
193
public DataSource testDataSource() {
194
// This will be excluded from proxying (configured in properties)
195
return new HikariDataSource();
196
}
197
}
198
```
199
200
## Auto-Configuration Details
201
202
DataSource auto-proxying is configured through `SeataDataSourceAutoConfiguration`:
203
204
```java { .api }
205
@Configuration(proxyBeanMethods = false)
206
@ConditionalOnExpression("${seata.enabled:true} && ${seata.enableAutoDataSourceProxy:true} && ${seata.enable-auto-data-source-proxy:true}")
207
@ConditionalOnBean(DataSource.class)
208
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
209
@AutoConfigureAfter(value = {SeataCoreAutoConfiguration.class},
210
name = "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration")
211
public class SeataDataSourceAutoConfiguration {
212
213
@Bean("seataAutoDataSourceProxyCreator")
214
@ConditionalOnMissingBean(SeataAutoDataSourceProxyCreator.class)
215
public static SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator(
216
SeataProperties seataProperties
217
);
218
}
219
```
220
221
**Activation Conditions:**
222
- `seata.enabled=true` (default)
223
- `seata.enableAutoDataSourceProxy=true` (default)
224
- At least one DataSource bean must be present
225
- Runs after core Seata auto-configuration
226
227
## JdbcTemplate Integration
228
229
DataSource proxying works seamlessly with Spring's JdbcTemplate:
230
231
```java
232
@Service
233
public class OrderService {
234
235
@Autowired
236
private JdbcTemplate jdbcTemplate;
237
238
@GlobalTransactional
239
public void createOrder(Order order) {
240
// JdbcTemplate uses the proxied DataSource automatically
241
String sql = "INSERT INTO orders (id, customer_id, amount) VALUES (?, ?, ?)";
242
jdbcTemplate.update(sql, order.getId(), order.getCustomerId(), order.getAmount());
243
244
// Transaction coordinates with other services
245
paymentService.processPayment(order.getAmount());
246
inventoryService.reserveItems(order.getItems());
247
}
248
}
249
```
250
251
## JPA/Hibernate Integration
252
253
Works with JPA EntityManager and Hibernate:
254
255
```java
256
@Entity
257
@Table(name = "orders")
258
public class Order {
259
@Id
260
private Long id;
261
private String customerId;
262
private BigDecimal amount;
263
// ... other fields
264
}
265
266
@Repository
267
public class OrderRepository {
268
269
@PersistenceContext
270
private EntityManager entityManager;
271
272
@GlobalTransactional
273
public void saveOrder(Order order) {
274
// EntityManager uses proxied DataSource
275
entityManager.persist(order);
276
277
// Distributed transaction coordination happens automatically
278
inventoryService.updateStock(order.getItems());
279
}
280
}
281
```
282
283
## Connection Pool Integration
284
285
Auto-proxying works with popular connection pools:
286
287
### HikariCP Configuration
288
289
```java
290
@Configuration
291
public class HikariDataSourceConfig {
292
293
@Bean
294
@ConfigurationProperties("spring.datasource.hikari")
295
public DataSource dataSource() {
296
// HikariCP DataSource will be automatically proxied
297
return DataSourceBuilder.create()
298
.type(HikariDataSource.class)
299
.build();
300
}
301
}
302
```
303
304
### Druid Configuration
305
306
```java
307
@Configuration
308
public class DruidDataSourceConfig {
309
310
@Bean
311
@ConfigurationProperties("spring.datasource.druid")
312
public DataSource dataSource() {
313
// Druid DataSource will be automatically proxied
314
return DruidDataSourceBuilder.create().build();
315
}
316
}
317
```
318
319
## Manual Proxy Creation (Alternative)
320
321
If you need manual control over DataSource proxying:
322
323
```java
324
@Configuration
325
public class ManualDataSourceConfig {
326
327
@Bean
328
@Primary
329
public DataSource dataSource() {
330
HikariDataSource originalDataSource = new HikariDataSource();
331
// Configure original DataSource...
332
333
// Manually create Seata proxy
334
return SeataDataSourceProxy.wrap(originalDataSource);
335
}
336
}
337
```
338
339
Disable auto-proxying when using manual proxies:
340
341
```properties
342
seata.enable-auto-data-source-proxy=false
343
```
344
345
## Performance Considerations
346
347
### AT Mode Performance
348
349
- **SQL Interception**: Minimal overhead for SQL parsing and modification
350
- **Undo Logs**: Additional storage and I/O for rollback capability
351
- **Lock Management**: Efficient optimistic locking with conflict detection
352
353
### XA Mode Performance
354
355
- **Two-Phase Commit**: Higher latency due to additional coordination phases
356
- **Resource Locking**: Longer lock holding times affecting concurrency
357
- **Network Overhead**: Additional communication with transaction coordinator
358
359
### Optimization Tips
360
361
```properties
362
# Connection pool optimization for Seata
363
spring.datasource.hikari.maximum-pool-size=20
364
spring.datasource.hikari.minimum-idle=5
365
spring.datasource.hikari.connection-timeout=60000
366
367
# AT mode optimization
368
seata.client.undo.log-serialization=jackson
369
seata.client.undo.compress.enable=true
370
```
371
372
## Troubleshooting
373
374
### Common Issues
375
376
1. **DataSource Not Proxied**: Check auto-configuration conditions and bean registration
377
2. **Connection Pool Issues**: Verify connection pool configuration and limits
378
3. **Transaction Isolation**: Review database isolation levels for AT mode
379
4. **Undo Log Errors**: Ensure undo_log table exists and is properly configured
380
381
### Debug Configuration
382
383
```properties
384
# Debug DataSource proxying
385
logging.level.io.seata.rm.datasource=DEBUG
386
logging.level.io.seata.spring.annotation.datasource=DEBUG
387
388
# Monitor connection usage
389
spring.datasource.hikari.leak-detection-threshold=60000
390
```
391
392
### Undo Log Table Setup
393
394
For AT mode, create the required undo log table:
395
396
```sql
397
-- MySQL example
398
CREATE TABLE `undo_log` (
399
`id` bigint(20) NOT NULL AUTO_INCREMENT,
400
`branch_id` bigint(20) NOT NULL,
401
`xid` varchar(100) NOT NULL,
402
`context` varchar(128) NOT NULL,
403
`rollback_info` longblob NOT NULL,
404
`log_status` int(11) NOT NULL,
405
`log_created` datetime NOT NULL,
406
`log_modified` datetime NOT NULL,
407
PRIMARY KEY (`id`),
408
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
409
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
410
```