0
# Transaction Configuration
1
2
Comprehensive configuration system supporting node identification, timeouts, object store types, recovery options, and runtime customization for Quarkus transaction management.
3
4
## Capabilities
5
6
### Runtime Configuration Properties
7
8
Core configuration properties for transaction manager runtime behavior.
9
10
```properties
11
# Node identification
12
quarkus.transaction-manager.node-name=quarkus
13
quarkus.transaction-manager.shorten-node-name-if-necessary=false
14
15
# Transaction timeouts
16
quarkus.transaction-manager.default-transaction-timeout=60s
17
18
# Recovery system
19
quarkus.transaction-manager.enable-recovery=false
20
quarkus.transaction-manager.recovery-modules=com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule,com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter
21
quarkus.transaction-manager.expiry-scanners=com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
22
quarkus.transaction-manager.xa-resource-orphan-filters=com.arjuna.ats.internal.jta.recovery.arjunacore.JTATransactionLogXAResourceOrphanFilter,com.arjuna.ats.internal.jta.recovery.arjunacore.JTANodeNameXAResourceOrphanFilter
23
24
# Object Store - File System (default)
25
quarkus.transaction-manager.object-store.type=file-system
26
quarkus.transaction-manager.object-store.directory=ObjectStore
27
28
# Object Store - JDBC
29
quarkus.transaction-manager.object-store.type=jdbc
30
quarkus.transaction-manager.object-store.datasource=<datasource-name>
31
quarkus.transaction-manager.object-store.create-table=false
32
quarkus.transaction-manager.object-store.drop-table=false
33
quarkus.transaction-manager.object-store.table-prefix=quarkus_
34
```
35
36
### TransactionManagerConfiguration Interface
37
38
Runtime configuration interface for programmatic access to transaction manager settings.
39
40
```java { .api }
41
/**
42
* Runtime configuration interface for transaction manager
43
*/
44
interface TransactionManagerConfiguration {
45
46
/**
47
* Node identifier for transaction manager
48
* Used for transaction recovery and distributed transaction coordination
49
* @return Node name string (default: "quarkus")
50
*/
51
String nodeName();
52
53
/**
54
* Whether to automatically shorten node name if it exceeds system limits
55
* @return true if automatic shortening is enabled (default: false)
56
*/
57
boolean shortenNodeNameIfNecessary();
58
59
/**
60
* Default timeout for transactions when not explicitly specified
61
* @return Duration representing default timeout (default: 60 seconds)
62
*/
63
Duration defaultTransactionTimeout();
64
65
/**
66
* Whether transaction recovery is enabled
67
* Recovery allows incomplete transactions to be resolved after crashes
68
* @return true if recovery is enabled (default: false)
69
*/
70
boolean enableRecovery();
71
72
/**
73
* List of recovery module class names for transaction recovery
74
* @return List of fully qualified class names
75
*/
76
List<String> recoveryModules();
77
78
/**
79
* List of expiry scanner class names for cleaning up expired transactions
80
* @return List of fully qualified class names
81
*/
82
List<String> expiryScanners();
83
84
/**
85
* List of XA resource orphan filter class names
86
* @return List of fully qualified class names
87
*/
88
List<String> xaResourceOrphanFilters();
89
90
/**
91
* Object store configuration for transaction logs
92
* @return ObjectStoreConfig instance
93
*/
94
ObjectStoreConfig objectStore();
95
}
96
```
97
98
**Usage Examples:**
99
100
```java
101
import io.quarkus.narayana.jta.runtime.TransactionManagerConfiguration;
102
103
@ApplicationScoped
104
public class TransactionMonitoringService {
105
106
@Inject
107
TransactionManagerConfiguration config;
108
109
public void logConfiguration() {
110
logger.info("Node name: " + config.nodeName());
111
logger.info("Default timeout: " + config.defaultTransactionTimeout());
112
logger.info("Recovery enabled: " + config.enableRecovery());
113
}
114
115
public boolean isRecoveryEnabled() {
116
return config.enableRecovery();
117
}
118
119
public Duration getDefaultTimeout() {
120
return config.defaultTransactionTimeout();
121
}
122
}
123
```
124
125
### Object Store Configuration
126
127
Configuration for transaction log storage, supporting both file system and JDBC storage.
128
129
```java { .api }
130
/**
131
* Object store configuration for transaction persistence
132
*/
133
interface ObjectStoreConfig {
134
135
/**
136
* Directory for file system object store
137
* @return Directory path (default: "ObjectStore")
138
*/
139
String directory();
140
141
/**
142
* Type of object store to use
143
* @return ObjectStoreType enum value
144
*/
145
ObjectStoreType type();
146
147
/**
148
* Datasource name for JDBC object store
149
* Only used when type is JDBC
150
* @return Optional datasource name
151
*/
152
Optional<String> datasource();
153
154
/**
155
* Whether to create object store table automatically
156
* Only applies to JDBC object store
157
* @return true if table should be created (default: false)
158
*/
159
boolean createTable();
160
161
/**
162
* Whether to drop object store table on shutdown
163
* Only applies to JDBC object store
164
* @return true if table should be dropped (default: false)
165
*/
166
boolean dropTable();
167
168
/**
169
* Prefix for object store table names
170
* Only applies to JDBC object store
171
* @return Table prefix (default: "quarkus_")
172
*/
173
String tablePrefix();
174
}
175
176
/**
177
* Object store type enumeration
178
*/
179
enum ObjectStoreType {
180
/** File system based storage (default) */
181
File_System,
182
183
/** JDBC database based storage */
184
JDBC
185
}
186
```
187
188
**Configuration Examples:**
189
190
```properties
191
# File System Object Store (Development)
192
quarkus.transaction-manager.object-store.type=file-system
193
quarkus.transaction-manager.object-store.directory=/app/transaction-logs
194
195
# JDBC Object Store (Production)
196
quarkus.transaction-manager.object-store.type=jdbc
197
quarkus.transaction-manager.object-store.datasource=transaction-log
198
quarkus.transaction-manager.object-store.create-table=true
199
quarkus.transaction-manager.object-store.table-prefix=app_tx_
200
```
201
202
### Node Name Configuration
203
204
```java
205
/**
206
* Node name configuration affects transaction recovery and clustering
207
*/
208
@ApplicationScoped
209
public class NodeConfigurationService {
210
211
@ConfigProperty(name = "quarkus.transaction-manager.node-name")
212
String nodeName;
213
214
@ConfigProperty(name = "quarkus.transaction-manager.shorten-node-name-if-necessary")
215
boolean shortenNodeName;
216
217
public String getEffectiveNodeName() {
218
String effectiveName = nodeName;
219
220
if (shortenNodeName && effectiveName.length() > 28) {
221
// Narayana has a 28-character limit for node names
222
effectiveName = effectiveName.substring(0, 28);
223
logger.info("Node name shortened from {} to {}", nodeName, effectiveName);
224
}
225
226
return effectiveName;
227
}
228
}
229
```
230
231
### Timeout Configuration
232
233
Multiple ways to configure transaction timeouts at different levels.
234
235
```java { .api }
236
/**
237
* Timeout configuration hierarchy (highest precedence first):
238
* 1. Programmatic timeout (QuarkusTransaction.beginOptions().timeout())
239
* 2. @TransactionConfiguration annotation timeout
240
* 3. Configuration property referenced by @TransactionConfiguration
241
* 4. Global default timeout configuration
242
*/
243
```
244
245
**Configuration Examples:**
246
247
```properties
248
# Global default timeout
249
quarkus.transaction-manager.default-transaction-timeout=120s
250
251
# Custom timeout properties for specific use cases
252
batch.processing.timeout=600
253
critical.operation.timeout=30
254
quick.operation.timeout=5
255
```
256
257
**Usage in Code:**
258
259
```java
260
@ApplicationScoped
261
public class TimeoutConfigurationService {
262
263
// Global default (120s from config)
264
@Transactional
265
public void standardOperation() { }
266
267
// Method-level timeout override
268
@Transactional
269
@TransactionConfiguration(timeout = 60)
270
public void mediumOperation() { }
271
272
// Property-based timeout with fallback
273
@Transactional
274
@TransactionConfiguration(
275
timeout = 30, // Fallback value
276
timeoutFromConfigProperty = "critical.operation.timeout"
277
)
278
public void criticalOperation() { }
279
280
// Programmatic timeout (highest precedence)
281
public void programmaticTimeout() {
282
QuarkusTransaction.begin(
283
QuarkusTransaction.beginOptions().timeout(45)
284
);
285
// This uses 45s regardless of other configurations
286
}
287
}
288
```
289
290
### Recovery Configuration
291
292
Transaction recovery configuration for production environments.
293
294
```properties
295
# Enable recovery for production
296
quarkus.transaction-manager.enable-recovery=true
297
298
# Recovery with JDBC object store
299
quarkus.transaction-manager.object-store.type=jdbc
300
quarkus.transaction-manager.object-store.datasource=recovery-db
301
quarkus.transaction-manager.object-store.create-table=true
302
```
303
304
**Recovery Service Usage:**
305
306
```java
307
@ApplicationScoped
308
public class RecoveryMonitoringService {
309
310
@Inject
311
TransactionManagerConfiguration config;
312
313
@Scheduled(every = "1h")
314
public void checkRecoveryStatus() {
315
if (config.enableRecovery()) {
316
logger.info("Transaction recovery is enabled");
317
// Monitor recovery process
318
checkForOrphanedTransactions();
319
}
320
}
321
322
private void checkForOrphanedTransactions() {
323
// Implementation depends on object store type
324
if (config.objectStore().type() == ObjectStoreType.JDBC) {
325
checkJdbcObjectStoreHealth();
326
} else {
327
checkFileSystemObjectStoreHealth();
328
}
329
}
330
}
331
```
332
333
### Environment-Specific Configuration
334
335
**Development Configuration:**
336
337
```properties
338
# Development - simple file-based storage
339
quarkus.transaction-manager.node-name=dev-node
340
quarkus.transaction-manager.default-transaction-timeout=30s
341
quarkus.transaction-manager.enable-recovery=false
342
quarkus.transaction-manager.object-store.type=file-system
343
quarkus.transaction-manager.object-store.directory=target/tx-logs
344
```
345
346
**Production Configuration:**
347
348
```properties
349
# Production - JDBC storage with recovery
350
quarkus.transaction-manager.node-name=${hostname:prod-node}
351
quarkus.transaction-manager.default-transaction-timeout=60s
352
quarkus.transaction-manager.enable-recovery=true
353
quarkus.transaction-manager.object-store.type=jdbc
354
quarkus.transaction-manager.object-store.datasource=transaction-log
355
quarkus.transaction-manager.object-store.create-table=false
356
quarkus.transaction-manager.object-store.table-prefix=prod_tx_
357
```
358
359
**Kubernetes/Cloud Configuration:**
360
361
```properties
362
# Cloud-native configuration
363
quarkus.transaction-manager.node-name=${HOSTNAME:${RANDOM_UUID}}
364
quarkus.transaction-manager.shorten-node-name-if-necessary=true
365
quarkus.transaction-manager.default-transaction-timeout=120s
366
quarkus.transaction-manager.enable-recovery=true
367
quarkus.transaction-manager.object-store.type=jdbc
368
quarkus.transaction-manager.object-store.datasource=shared-transaction-log
369
```
370
371
### Integration with Other Quarkus Extensions
372
373
**Hibernate ORM Integration:**
374
375
```properties
376
# Ensure transaction manager is available before Hibernate
377
quarkus.hibernate-orm.transaction-manager=quarkus-jta
378
379
# Database configuration for both app data and transaction logs
380
quarkus.datasource.db-kind=postgresql
381
quarkus.datasource.username=app_user
382
quarkus.datasource.password=app_password
383
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/app_db
384
385
# Separate datasource for transaction logs
386
quarkus.datasource.tx-log.db-kind=postgresql
387
quarkus.datasource.tx-log.username=tx_user
388
quarkus.datasource.tx-log.password=tx_password
389
quarkus.datasource.tx-log.jdbc.url=jdbc:postgresql://localhost/tx_log_db
390
391
quarkus.transaction-manager.object-store.datasource=tx-log
392
```
393
394
**JMS Integration:**
395
396
```properties
397
# JMS with XA transactions
398
quarkus.artemis.xa=true
399
quarkus.transaction-manager.enable-recovery=true
400
```
401
402
## Best Practices
403
404
### Node Name Guidelines
405
406
```properties
407
# ✅ Good: Descriptive and unique node names
408
quarkus.transaction-manager.node-name=order-service-prod-01
409
quarkus.transaction-manager.node-name=payment-processor-${HOSTNAME}
410
411
# ✅ Good: Use environment variables for dynamic naming
412
quarkus.transaction-manager.node-name=${NODE_NAME:default-node}
413
414
# ❌ Avoid: Generic names in clustered environments
415
quarkus.transaction-manager.node-name=node1
416
```
417
418
### Timeout Configuration Strategy
419
420
```properties
421
# ✅ Good: Different timeouts for different operation types
422
quarkus.transaction-manager.default-transaction-timeout=60s
423
batch.processing.timeout=1800s
424
quick.query.timeout=10s
425
external.api.timeout=30s
426
427
# ✅ Good: Use configuration properties for flexibility
428
@TransactionConfiguration(timeoutFromConfigProperty = "batch.processing.timeout")
429
```
430
431
### Object Store Selection
432
433
```properties
434
# ✅ Development: File system for simplicity
435
%dev.quarkus.transaction-manager.object-store.type=file-system
436
%dev.quarkus.transaction-manager.enable-recovery=false
437
438
# ✅ Production: JDBC for reliability and clustering
439
%prod.quarkus.transaction-manager.object-store.type=jdbc
440
%prod.quarkus.transaction-manager.enable-recovery=true
441
%prod.quarkus.transaction-manager.object-store.create-table=false
442
```
443
444
### Monitoring and Observability
445
446
```java
447
@ApplicationScoped
448
public class TransactionMetricsService {
449
450
@Inject
451
TransactionManagerConfiguration config;
452
453
@Inject
454
MeterRegistry meterRegistry;
455
456
@PostConstruct
457
void initMetrics() {
458
Gauge.builder("transaction.default.timeout.seconds")
459
.register(meterRegistry, this,
460
service -> service.config.defaultTransactionTimeout().toSeconds());
461
462
Gauge.builder("transaction.recovery.enabled")
463
.register(meterRegistry, this,
464
service -> service.config.enableRecovery() ? 1 : 0);
465
}
466
}
467
```