Back to Conductor

JDBC Configuration

ai/JDBC_CONFIGURATION.md

2019-04-12-13007.9 KB
Original Source

JDBC Configuration

This document describes the configuration format for JDBC database connections in Conductor.

Overview

Conductor supports configuring multiple named JDBC instances for use by the JDBC worker task. This allows you to:

  • Connect to multiple databases (MySQL, PostgreSQL, Oracle, etc.)
  • Separate environments (prod, dev, staging)
  • Use different connection pool settings per use case (read-heavy vs write-heavy)

Configuration Format

JDBC instances are configured using a list-based approach under conductor.jdbc.instances:

yaml
conductor:
  jdbc:
    instances:
      - name: "instance-name"        # Unique identifier for this instance
        connection:                   # Connection configuration
          datasourceURL: "jdbc:..."   # JDBC connection URL
          jdbcDriver: "..."           # JDBC driver class (optional, auto-detected from URL)
          user: "..."                 # Database username
          password: "..."             # Database password
          # ... pool settings

Configuration Examples

Single MySQL Instance

yaml
conductor:
  jdbc:
    instances:
      - name: "mysql-prod"
        connection:
          datasourceURL: "jdbc:mysql://prod-db:3306/myapp"
          jdbcDriver: "com.mysql.cj.jdbc.Driver"
          user: "conductor"
          password: "secret"
          maximumPoolSize: 20
          minimumIdle: 5

Multiple Instances

yaml
conductor:
  jdbc:
    instances:
      - name: "mysql-prod"
        connection:
          datasourceURL: "jdbc:mysql://prod-db:3306/myapp"
          jdbcDriver: "com.mysql.cj.jdbc.Driver"
          user: "conductor"
          password: "prod-secret"
          maximumPoolSize: 20

      - name: "postgres-analytics"
        connection:
          datasourceURL: "jdbc:postgresql://analytics-db:5432/warehouse"
          user: "analyst"
          password: "analytics-secret"
          maximumPoolSize: 10

      - name: "mysql-staging"
        connection:
          datasourceURL: "jdbc:mysql://staging-db:3306/myapp"
          jdbcDriver: "com.mysql.cj.jdbc.Driver"
          user: "conductor"
          password: "staging-secret"
          maximumPoolSize: 5
          minimumIdle: 1

Usage in Workflows

When using the JDBC task in your workflows, reference the instance by its configured name using connectionId:

json
{
  "name": "query_users",
  "taskReferenceName": "query_users_ref",
  "type": "JDBC",
  "inputParameters": {
    "connectionId": "mysql-prod",
    "type": "SELECT",
    "statement": "SELECT id, name, email FROM users WHERE status = ?",
    "parameters": ["active"]
  }
}

SELECT Example

json
{
  "name": "find_orders",
  "taskReferenceName": "find_orders_ref",
  "type": "JDBC",
  "inputParameters": {
    "connectionId": "postgres-analytics",
    "type": "SELECT",
    "statement": "SELECT order_id, total FROM orders WHERE customer_id = ?",
    "parameters": ["${workflow.input.customerId}"]
  }
}

Output:

json
{
  "result": [
    {"order_id": 101, "total": 49.99},
    {"order_id": 205, "total": 129.50}
  ]
}

UPDATE Example

json
{
  "name": "update_status",
  "taskReferenceName": "update_status_ref",
  "type": "JDBC",
  "inputParameters": {
    "connectionId": "mysql-prod",
    "type": "UPDATE",
    "statement": "UPDATE orders SET status = ? WHERE order_id = ?",
    "parameters": ["shipped", "${workflow.input.orderId}"],
    "expectedUpdateCount": 1
  }
}

Output:

json
{
  "update_count": 1
}

If the actual update count does not match expectedUpdateCount, the transaction is rolled back and the task fails.

Connection Configuration Options

PropertyTypeDefaultDescription
datasourceURLStringRequiredJDBC connection URL
jdbcDriverStringAuto-detectedJDBC driver class name
userStringOptionalDatabase username
passwordStringOptionalDatabase password
maximumPoolSizeInteger32Maximum connections in the pool
minimumIdleInteger2Minimum idle connections
idleTimeoutMsLong30000Idle connection timeout (ms)
connectionTimeoutLong30000Connection acquisition timeout (ms)
leakDetectionThresholdLong60000Leak detection threshold (ms)
maxLifetimeLong1800000Maximum connection lifetime (ms)

Migration from Old Configuration

Old Format

properties
conductor.worker.jdbc.connectionIds=mysql,postgres
conductor.worker.jdbc.mysql.connectionURL=jdbc:mysql://localhost:3306/db
conductor.worker.jdbc.mysql.driverClassName=com.mysql.cj.jdbc.Driver
conductor.worker.jdbc.mysql.username=root
conductor.worker.jdbc.mysql.password=secret
conductor.worker.jdbc.mysql.maximum-pool-size=10

conductor.worker.jdbc.postgres.connectionURL=jdbc:postgresql://localhost:5432/db
conductor.worker.jdbc.postgres.driverClassName=org.postgresql.Driver
conductor.worker.jdbc.postgres.username=pguser
conductor.worker.jdbc.postgres.password=pgpass

New Format

yaml
conductor:
  jdbc:
    instances:
      - name: "mysql"
        connection:
          datasourceURL: "jdbc:mysql://localhost:3306/db"
          jdbcDriver: "com.mysql.cj.jdbc.Driver"
          user: "root"
          password: "secret"
          maximumPoolSize: 10

      - name: "postgres"
        connection:
          datasourceURL: "jdbc:postgresql://localhost:5432/db"
          jdbcDriver: "org.postgresql.Driver"
          user: "pguser"
          password: "pgpass"

Note: The old conductor.worker.jdbc.* format is still supported for backwards compatibility. If no conductor.jdbc.instances are configured, the system automatically falls back to reading the legacy format. The old and new formats are mutually exclusive -- if new-format instances are found, the legacy format is ignored.

Property Name Mapping

Old PropertyNew Property
connectionURLdatasourceURL
driverClassNamejdbcDriver
usernameuser
passwordpassword
maximum-pool-sizemaximumPoolSize
idle-timeout-msidleTimeoutMs
minimum-idleminimumIdle

Best Practices

  1. Use descriptive names: Choose instance names that clearly indicate their purpose (e.g., mysql-prod, postgres-analytics, oracle-reporting)

  2. Separate read/write pools: For high-throughput systems, configure separate instances for read and write operations with appropriate pool sizes

  3. Right-size connection pools: Set maximumPoolSize based on your database capacity and workload. A common formula is connections = (core_count * 2) + effective_spindle_count

  4. Enable leak detection: The default leakDetectionThreshold of 60 seconds logs warnings for connections held longer than expected

  5. Use parameterized queries: Always use ? placeholders with the parameters list instead of string concatenation to prevent SQL injection

  6. Set expectedUpdateCount: For critical UPDATE/INSERT/DELETE operations, set expectedUpdateCount to automatically rollback if the affected row count doesn't match

Troubleshooting

Instance Not Found

If you see "JDBC instance not found: xyz", check:

  1. The connectionId in your workflow matches the configured name exactly
  2. The instance is properly configured in your application.yml/properties
  3. The application has been restarted after configuration changes

Connection Timeout

If connections are timing out:

  1. Verify network connectivity to the database
  2. Check connectionTimeout value (default 30 seconds)
  3. Ensure the connection pool is not exhausted (increase maximumPoolSize if needed)
  4. Check database max connections limit

Connection Leaks

If you see leak detection warnings:

  1. Ensure all connections are properly closed (the JDBC worker handles this automatically)
  2. If using custom integrations, wrap connection usage in try-with-resources
  3. Review leakDetectionThreshold setting