Skip to content

fix(adapter-mariadb): release pooled connections and harden transaction cleanup#29612

Open
andychinghk01 wants to merge 1 commit into
prisma:mainfrom
andychinghk01:fix/mariadb-idletimeout-28964
Open

fix(adapter-mariadb): release pooled connections and harden transaction cleanup#29612
andychinghk01 wants to merge 1 commit into
prisma:mainfrom
andychinghk01:fix/mariadb-idletimeout-28964

Conversation

@andychinghk01

Copy link
Copy Markdown

Summary

Fixes #28964.

The MariaDB adapter previously called mariadb.Connection#end() to dispose of a transaction connection. For a PoolConnection end() happens to be aliased to release(), so in practice it does return the connection to the pool — but the intent is ambiguous, and the same code path is reachable with a plain mariadb.Connection (e.g. in tests), where end() permanently closes the connection. The transaction failure path also removed the connection's error listener after releasing the connection and without a try/finally, so a throw during teardown would leak the listener onto the next caller.

Changes

  • Introduce a small releaseConnection() helper that prefers PoolConnection#release() and falls back to Connection#end().
  • Use it from MariaDbTransaction#commit and #rollback.
  • In startTransaction's catch path, detach the error listener before releasing the connection and wrap the release in try/finally so the connection is always returned to the pool, even if cleanup throws.

Tests

Added unit tests in packages/adapter-mariadb/src/mariadb.test.ts:

  • release() is used for pool connections; end() fallback for non-pool connections.
  • The transaction error listener is detached on commit.
  • The transaction error listener is detached and the connection is released on startTransaction failure.

All 26 adapter unit tests pass (pnpm --filter @prisma/adapter-mariadb test).

Out-of-band verification

I also ran an end-to-end harness with Docker (mariadb:10.11) covering:

  1. connectionLimit=100, 100 concurrent transactions → 100 idle conns after release ✅
  2. Two sequential rounds of 100 → pool reuses, stays at 100 ✅
  3. 200 concurrent vs connectionLimit=100 → capped at 100, no leak ✅
  4. idleTimeout=10s → pool drains to minimumIdle after the window ✅
  5. After drain, a new burst grows the pool again ✅

Closes #28964

…on cleanup

Fixes prisma#28964

The MariaDB adapter previously called `mariadb.Connection#end()` to dispose
of a transaction connection. For a `PoolConnection` `end()` is aliased to
`release()`, so in practice it does return the connection to the pool — but
the intent is ambiguous, and the same code path is reachable with a plain
`mariadb.Connection` (e.g. in tests), where `end()` permanently closes the
connection. The transaction failure path also removed the connection's
`error` listener *after* releasing the connection and without a try/finally,
so a throw during teardown would leak the listener onto the next caller.

Changes:

* Introduce a small `releaseConnection()` helper that prefers
  `PoolConnection#release()` and falls back to `Connection#end()`.
* Use it from `MariaDbTransaction#commit` and `#rollback`.
* In `startTransaction`'s catch path, detach the error listener before
  releasing the connection and wrap the release in try/finally so the
  connection is always returned to the pool.

Tests:

* Cover `release()` vs `end()` fallback.
* Cover listener cleanup on `commit`.
* Cover listener cleanup on `startTransaction` failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Copilot seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ede67556-70f8-4f48-bc6f-40d06381fa0f

📥 Commits

Reviewing files that changed from the base of the PR and between 42f9102 and 60c9938.

📒 Files selected for processing (2)
  • packages/adapter-mariadb/src/mariadb.test.ts
  • packages/adapter-mariadb/src/mariadb.ts

Summary by CodeRabbit

  • Bug Fixes
    • Fixed MariaDB transaction handling to properly manage database connections during commit and rollback operations
    • Improved connection reuse and stability in transaction scenarios, preventing connection leaks

Walkthrough

The MariaDB adapter now properly returns transaction connections to the connection pool instead of permanently closing them. A new releaseConnection() helper intelligently uses PoolConnection#release() when available and falls back to end() for non-pool connections. commit() and rollback() release connections via this helper, and error handling in startTransaction ensures listeners are cleaned up and connections are released even when BEGIN fails.

Changes

Transaction connection pool management

Layer / File(s) Summary
Connection pool release helper
packages/adapter-mariadb/src/mariadb.ts
New releaseConnection(conn) internal helper that calls PoolConnection#release() when available, otherwise falls back to conn.end() for non-pool connections.
Transaction commit and rollback pool release
packages/adapter-mariadb/src/mariadb.ts
MariaDbTransaction.commit() and rollback() now call releaseConnection(this.client) in their finally blocks instead of calling end(), returning connections to the pool.
Transaction start error handling and listener cleanup
packages/adapter-mariadb/src/mariadb.ts
startTransaction detaches the connection error listener with conn.off('error', onError) in the success path cleanup. When BEGIN fails, the error path detaches the listener and calls releaseConnection(conn) inside a try/finally, replacing the prior conn.end() + cleanup() flow.
Transaction pool behavior tests
packages/adapter-mariadb/src/mariadb.test.ts
Comprehensive Vitest suite for PrismaMariaDbAdapter transaction behavior: mock connection helper supporting pool operations and listener tracking; tests verifying commit() and rollback() use release(), error listener cleanup after commit(), connection cleanup when BEGIN fails, and fallback to end() for non-pool connections.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main changes: fixing the adapter to properly release pooled connections and improve transaction cleanup error handling.
Description check ✅ Passed The description is well-related to the changeset, explaining the root cause of issue #28964, the implemented fixes, added tests, and verification steps.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #28964: introduces releaseConnection() helper to properly return connections to the pool, fixes the transaction failure cleanup path with try/finally, adds comprehensive unit tests, and includes out-of-band E2E verification.
Out of Scope Changes check ✅ Passed All changes directly address issue #28964: the releaseConnection() helper, transaction commit/rollback modifications, startTransaction error handling, and new unit tests are all in-scope improvements to fix the connection pool management.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aqrln aqrln left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer

3 participants