or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connection-pooling.mddatabase-configuration.mddatabase-management.mddatabase-operations.mddependency-injection.mdindex.md

connection-pooling.mddocs/

0

# Connection Pooling

1

2

HikariCP-based connection pool implementation with comprehensive configuration options, performance monitoring, and lifecycle management.

3

4

## Capabilities

5

6

### ConnectionPool Interface

7

8

Abstract interface for connection pool implementations.

9

10

```scala { .api }

11

trait ConnectionPool {

12

/** Create a data source with the given configuration */

13

def create(name: String, dbConfig: DatabaseConfig, configuration: Config): DataSource

14

/** Close the given data source */

15

def close(dataSource: DataSource): Unit

16

}

17

```

18

19

### ConnectionPool Factory Methods

20

21

Factory methods for creating connection pool instances.

22

23

```scala { .api }

24

object ConnectionPool {

25

/** Load a connection pool from a configured connection pool with Injector support */

26

def fromConfig(

27

config: String,

28

injector: Injector,

29

environment: Environment,

30

default: ConnectionPool

31

): ConnectionPool

32

33

/** Load a connection pool from configuration for compile-time DI */

34

def fromConfig(

35

config: String,

36

environment: Environment,

37

default: ConnectionPool

38

): ConnectionPool

39

40

/** Extract and process database URL, supporting shortcut formats */

41

def extractUrl(maybeUrl: Option[String], mode: Mode): (Option[String], Option[(String, String)])

42

43

/** Wrap a data source for SQL logging if logSql is enabled */

44

private[db] def wrapToLogSql(dataSource: DataSource, configuration: Config): DataSource

45

46

/** Unwrap a data source if it has been wrapped for SQL logging */

47

private[db] def unwrap(dataSource: DataSource): DataSource

48

}

49

```

50

51

**Usage Examples:**

52

53

```scala

54

import play.api.db._

55

import play.api.Environment

56

57

// Create connection pool for compile-time DI

58

val environment = Environment.simple()

59

val defaultPool = new HikariCPConnectionPool(environment)

60

val pool = ConnectionPool.fromConfig("hikaricp", environment, defaultPool)

61

62

// URL extraction with credential parsing

63

val (extractedUrl, credentials) = ConnectionPool.extractUrl(

64

Some("postgres://user:pass@localhost:5432/mydb"),

65

play.api.Mode.Dev

66

)

67

// extractedUrl: Some("jdbc:postgresql://localhost:5432/mydb")

68

// credentials: Some(("user", "pass"))

69

```

70

71

### HikariCP Implementation

72

73

HikariCP-based implementation of the ConnectionPool interface.

74

75

```scala { .api }

76

@Singleton

77

class HikariCPConnectionPool @Inject()(environment: Environment) extends ConnectionPool {

78

/** Create a HikariCP data source with the given configuration */

79

override def create(name: String, dbConfig: DatabaseConfig, configuration: Config): DataSource

80

/** Close the HikariCP data source */

81

override def close(dataSource: DataSource): Unit

82

}

83

```

84

85

**Usage Examples:**

86

87

```scala

88

import play.api.db._

89

import play.api.{Configuration, Environment}

90

import com.typesafe.config.ConfigFactory

91

92

val environment = Environment.simple()

93

val pool = new HikariCPConnectionPool(environment)

94

95

val dbConfig = DatabaseConfig(

96

driver = Some("org.postgresql.Driver"),

97

url = Some("jdbc:postgresql://localhost/myapp"),

98

username = Some("dbuser"),

99

password = Some("dbpass"),

100

jndiName = None

101

)

102

103

val config = ConfigFactory.parseString("""

104

hikaricp {

105

maximumPoolSize = 20

106

minimumIdle = 5

107

connectionTimeout = 30 seconds

108

idleTimeout = 10 minutes

109

maxLifetime = 30 minutes

110

}

111

""")

112

113

val dataSource = pool.create("myapp", dbConfig, config)

114

try {

115

val connection = dataSource.getConnection()

116

// Use connection...

117

connection.close()

118

} finally {

119

pool.close(dataSource)

120

}

121

```

122

123

### HikariCP Configuration

124

125

Comprehensive configuration options for HikariCP connection pools.

126

127

```scala { .api }

128

private[db] class HikariCPConfig(dbConfig: DatabaseConfig, configuration: Configuration) {

129

def toHikariConfig: HikariConfig

130

}

131

```

132

133

**Configuration Properties:**

134

135

Essential configurations:

136

- `dataSourceClassName` - Data source class name (alternative to driver/url)

137

- `jdbcUrl` - JDBC URL (from dbConfig.url)

138

- `driverClassName` - JDBC driver class (from dbConfig.driver)

139

- `username` - Database username (from dbConfig.username)

140

- `password` - Database password (from dbConfig.password)

141

142

Frequently used:

143

- `autoCommit` - Auto-commit behavior (default: true)

144

- `connectionTimeout` - Maximum wait time for connection (default: 30 seconds)

145

- `idleTimeout` - Maximum idle time before connection is retired (default: 10 minutes)

146

- `maxLifetime` - Maximum lifetime of a connection (default: 30 minutes)

147

- `connectionTestQuery` - Query to validate connections

148

- `minimumIdle` - Minimum number of idle connections

149

- `maximumPoolSize` - Maximum number of connections in pool (default: 10)

150

- `poolName` - User-defined name for the connection pool

151

152

Infrequently used:

153

- `initializationFailTimeout` - Pool initialization failure timeout

154

- `isolateInternalQueries` - Isolate internal pool queries

155

- `allowPoolSuspension` - Allow pool suspension

156

- `readOnly` - Default read-only mode for connections

157

- `registerMbeans` - Register JMX management beans

158

- `connectionInitSql` - SQL executed after connection creation

159

- `catalog` - Default catalog name

160

- `transactionIsolation` - Default transaction isolation level

161

- `validationTimeout` - Maximum time for connection validation

162

- `leakDetectionThreshold` - Connection leak detection threshold

163

164

**Configuration Example:**

165

166

```hocon

167

db.default {

168

driver = "org.postgresql.Driver"

169

url = "jdbc:postgresql://localhost/myapp"

170

username = "dbuser"

171

password = "dbpass"

172

173

# HikariCP specific settings

174

hikaricp {

175

# Pool sizing

176

minimumIdle = 5

177

maximumPoolSize = 20

178

179

# Connection timeouts

180

connectionTimeout = 30 seconds

181

idleTimeout = 10 minutes

182

maxLifetime = 30 minutes

183

184

# Connection testing

185

connectionTestQuery = "SELECT 1"

186

187

# Pool behavior

188

autoCommit = true

189

readOnly = false

190

191

# Monitoring

192

registerMbeans = true

193

leakDetectionThreshold = 60 seconds

194

195

# Data source properties

196

dataSource {

197

cachePrepStmts = true

198

prepStmtCacheSize = 250

199

prepStmtCacheSqlLimit = 2048

200

useServerPrepStmts = true

201

}

202

}

203

204

# SQL logging

205

logSql = false

206

}

207

```

208

209

### Database URL Parsing

210

211

Support for shortcut URL formats with automatic credential extraction.

212

213

**Supported URL Formats:**

214

215

PostgreSQL shortcut:

216

```

217

postgres://username:password@host/database

218

```

219

Converts to:

220

```

221

jdbc:postgresql://host/database

222

```

223

224

MySQL shortcut:

225

```

226

mysql://username:password@host/database

227

```

228

Converts to:

229

```

230

jdbc:mysql://host/database?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci

231

```

232

233

H2 development mode:

234

```

235

jdbc:h2:mem:testdb

236

```

237

Automatically adds `DB_CLOSE_DELAY=-1` in development mode.

238

239

**Usage Examples:**

240

241

```scala

242

import play.api.db.ConnectionPool

243

import play.api.Mode

244

245

// PostgreSQL shortcut URL

246

val (pgUrl, pgCreds) = ConnectionPool.extractUrl(

247

Some("postgres://myuser:mypass@db.example.com/production"),

248

Mode.Prod

249

)

250

// pgUrl: Some("jdbc:postgresql://db.example.com/production")

251

// pgCreds: Some(("myuser", "mypass"))

252

253

// MySQL shortcut URL

254

val (mysqlUrl, mysqlCreds) = ConnectionPool.extractUrl(

255

Some("mysql://app:secret@mysql.example.com/appdb"),

256

Mode.Prod

257

)

258

// mysqlUrl: Some("jdbc:mysql://mysql.example.com/appdb?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci")

259

// mysqlCreds: Some(("app", "secret"))

260

261

// H2 in development

262

val (h2Url, h2Creds) = ConnectionPool.extractUrl(

263

Some("jdbc:h2:mem:testdb"),

264

Mode.Dev

265

)

266

// h2Url: Some("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1")

267

// h2Creds: None

268

```

269

270

### SQL Logging

271

272

Optional SQL logging capability using jdbcdslog proxy.

273

274

```scala { .api }

275

private[db] def wrapToLogSql(dataSource: DataSource, configuration: Config): DataSource

276

private[db] def unwrap(dataSource: DataSource): DataSource

277

```

278

279

**Configuration:**

280

281

```hocon

282

db.default {

283

# Enable SQL logging

284

logSql = true

285

}

286

```

287

288

When enabled, all SQL statements and their parameters are logged to the console, useful for development and debugging.

289

290

### JNDI Support

291

292

Support for binding data sources to JNDI names.

293

294

**Configuration:**

295

296

```hocon

297

db.default {

298

driver = "org.postgresql.Driver"

299

url = "jdbc:postgresql://localhost/myapp"

300

jndiName = "java:comp/env/jdbc/MyAppDS"

301

}

302

```

303

304

The data source will be automatically bound to the specified JNDI name during creation.

305

306

## Performance Tuning

307

308

### Connection Pool Sizing

309

310

- **minimumIdle**: Should be same as maximumPoolSize for stable workloads

311

- **maximumPoolSize**: Formula: `((core_count * 2) + disk_count)` for typical OLTP workloads

312

- **connectionTimeout**: Should be longer than typical connection acquisition time

313

- **idleTimeout**: Should be shorter than database server connection timeout

314

315

### Prepared Statement Caching

316

317

```hocon

318

db.default {

319

hikaricp {

320

dataSource {

321

cachePrepStmts = true

322

prepStmtCacheSize = 250

323

prepStmtCacheSqlLimit = 2048

324

useServerPrepStmts = true

325

}

326

}

327

}

328

```

329

330

### Connection Leak Detection

331

332

```hocon

333

db.default {

334

hikaricp {

335

leakDetectionThreshold = 60 seconds

336

registerMbeans = true

337

}

338

}

339

```

340

341

## Error Handling

342

343

- **SQLException**: Thrown by underlying database operations

344

- **Connection timeouts**: Thrown when connection acquisition exceeds `connectionTimeout`

345

- **Pool exhaustion**: Thrown when no connections are available within timeout period

346

- **Configuration errors**: Thrown for invalid HikariCP configuration parameters

347

348

## Monitoring

349

350

- **JMX MBeans**: Enable with `registerMbeans = true` for pool metrics

351

- **Connection leak detection**: Configure `leakDetectionThreshold` to detect leaked connections

352

- **SQL logging**: Enable `logSql = true` for development debugging