4.9 KiB
4.9 KiB
Database Diagnostic Report - Exposed Framework Initialization
Diagnostic Results
✅ Database.connect() Calls Identified
Central Implementation:
- DatabaseFactory.kt (Line 66):
Database.connect(dataSource!!)- Uses HikariCP Connection Pooling
- Singleton pattern with proper configuration
- Supports connection validation and leak detection
Service-specific Configurations:
- Events Service: EventsDatabaseConfiguration.kt - uses DatabaseFactory.init()
- Horses Service: DatabaseConfiguration.kt - uses DatabaseFactory.init()
- Members Service: MembersDatabaseConfiguration.kt - uses DatabaseFactory.init()
- Masterdata Service: MasterdataDatabaseConfiguration.kt - uses DatabaseFactory.init()
⚠️ PROBLEM IDENTIFIED - Gateway Configuration:
- Gateway: DatabaseConfig.kt (Lines 25-30) - direct Database.connect() call
Database.connect( url = databaseUrl, driver = "org.postgresql.Driver", user = databaseUser, password = databasePassword )
✅ Exposed Operations (Transactions, Queries) Located
Schema Initialization (in @PostConstruct):
- All Services:
transaction { SchemaUtils.createMissingTablesAndColumns(...) } - Gateway:
transaction { SchemaUtils.createMissingTablesAndColumns(...) }for all contexts
Business Logic Transactions:
- TransactionalCreateHorseUseCase: Uses
DatabaseFactory.dbQuery { ... } - DatabaseMigrator: Uses
transaction { ... }for migrations
Test Transactions:
- SimpleDatabaseTest.kt: Direct
transaction { ... }calls in tests
✅ Initialization Order Analyzed
Correct Order in Services:
@PostConstruct→DatabaseFactory.init(config)→Database.connect()- Immediately after:
transaction { SchemaUtils.createMissingTablesAndColumns(...) } - Business Logic:
DatabaseFactory.dbQuery { ... }for transactions
⚠️ PROBLEM - Gateway Initialization:
- Ktor Application.configureDatabase() → direct
Database.connect() - Immediately after:
transaction { ... }for all service schemas
🚨 Identified Problems
1. Inconsistent Database.connect() Implementation
- Services: Use central DatabaseFactory with Connection Pooling
- Gateway: Direct Database.connect() without Connection Pooling
- Risk: Different connection quality and management
2. Potential Race Conditions
- Gateway and services initialize independently
- Both attempt to create schemas for the same tables
- Risk: Conflicts during parallel initialization
3. Violation of Separation of Concerns
- Gateway manages schemas for all services
- Services manage their own schemas
- Risk: Duplicate schema initialization
4. Missing Initialization Order Guarantees
- No explicit dependency order between Gateway and Services
- Risk: Exposed operations before Database.connect()
✅ Recommendations
1. Switch Gateway to DatabaseFactory
// Instead of direct Database.connect():
fun Application.configureDatabase() {
val config = DatabaseConfig.fromEnv() // or from Ktor Config
DatabaseFactory.init(config)
// Remove or coordinate schema initialization
}
2. Coordinate Schema Initialization
Option A: Only services manage their schemas (recommended)
// Gateway: Only connection, no schema initialization
fun Application.configureDatabase() {
DatabaseFactory.init(DatabaseConfig.fromEnv())
}
Option B: Centralized schema management
// Separate DatabaseSchemaInitializer with @Order annotation
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
class DatabaseSchemaInitializer {
@PostConstruct
fun initializeAllSchemas() {
// Schema initialization logic
}
}
3. Ensure Startup Order
// Services with @DependsOn
@Configuration
@DependsOn("databaseInitializer")
class HorsesDatabaseConfiguration {
// Configuration logic
}
4. Unified Configuration
// All components use DatabaseFactory
class SomeService {
suspend fun doSomething() {
DatabaseFactory.dbQuery {
// Exposed operations
}
}
}
📋 Summary
✅ Correctly implemented:
- All services use proper @PostConstruct → Database.connect() → Exposed operations sequence
- DatabaseFactory provides robust Connection Pool configuration
- Business logic uses correct transaction patterns
⚠️ To be fixed:
- Gateway Database.connect() inconsistency
- Potential race conditions in schema initialization
- Missing startup order coordination
🎯 Priority:
- High: Switch Gateway to DatabaseFactory
- Medium: Coordinate schema initialization
- Low: Explicitly define startup order
The initialization sequence is fundamentally correct, but the inconsistency between Gateway and Services should be resolved to avoid potential problems.
Last updated: July 25, 2025