Repository navigation
feat(sql) transactions, savepoints, connection pooling and reserve - #16381
Merged
Merged
Conversation
Collaborator
|
Updated 4:36 PM PT - Jan 18th, 2025
✅ @cirospaciari, your commit 66dd28e has passed in 🧪 try this PR locally: bunx bun-pr 16381 |
cirospaciari
force-pushed
the
ciro/postgres-transactions-cleanup
branch
from
January 14, 2025 01:18
130076c to
ff50783
Compare
cirospaciari
marked this pull request as ready for review
January 14, 2025 03:07
cirospaciari
force-pushed
the
ciro/postgres-transactions-cleanup
branch
from
January 14, 2025 03:07
0ea2f06 to
7b88aec
Compare
cirospaciari
marked this pull request as draft
January 14, 2025 03:15
cirospaciari
force-pushed
the
ciro/postgres-transactions-cleanup
branch
7 times, most recently
from
January 17, 2025 23:22
872492b to
71a5e32
Compare
cirospaciari
force-pushed
the
ciro/postgres-transactions-cleanup
branch
from
January 18, 2025 02:16
9eb2d9c to
a06f824
Compare
cirospaciari
marked this pull request as ready for review
January 18, 2025 02:16
| class PooledConnection { | ||
| pool: ConnectionPool; | ||
| connection: ReturnType<typeof createConnection>; | ||
| state: PooledConnectionState = PooledConnectionState.pending; |
Collaborator
There was a problem hiding this comment.
technically the flags and the connection state can be the same property since the connection state is 2 bits and the flags are 3 bits and we can go up to 32 bit int
Collaborator
There was a problem hiding this comment.
but its probably fine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
How did you verify your code works?
Add support for transactions:
BEGIN / COMMIT
await sql.begin([options = ''], fn) -> fn()SAVEPOINT
await sql.savepoint([name], fn) -> fn()ERR_POSTGRES_UNSAFE_TRANSACTIONerror is throw if BEGIN command is used without.begin(),max: 1or.reserve().Like
postgrespackage if returned an array of Promises on .begin or .savepoint it willPromise.allall promises before COMMIT.sql.transactionis a alias forsql.beginRESERVE
await sql.reserve()The reserve method pulls out a connection from the pool, and returns a client that wraps the single connection. This can be used for running queries on an isolated connection.
To make it simpler bun supports
Symbol.disposeandSymbol.asyncDisposeCalling
.reservein a reserved Sql will return a new reserved connection, not the same connection (behavior matchespostgrespackage).DISTRIBUTED TRANSACTIONS
await sql.beginDistributed(name, fn) -> fn()Also know as Two-Phase Commit, in a distributed transaction, Phase 1 involves the coordinator preparing nodes by ensuring data is written and ready to commit, while Phase 2 finalizes with nodes committing or rolling back based on the coordinator's decision, ensuring durability and releasing locks.
In PostgreSQL and MySQL distributed transactions persist beyond the original session, allowing privileged users or coordinators to commit/rollback them, ensuring support for distributed transactions, recovery, and administrative tasks.
beginDistributedwill automatic rollback if any exception are not caught, and you can commit and rollback later if everything goes well.PostgreSQL natively supports distributed transactions using PREPARE TRANSACTION, while MySQL uses XA Transactions, and MSSQL also supports distributed/XA transactions. However, in MSSQL, distributed transactions are tied to the original session, the DTC coordinator, and the specific connection. These transactions are automatically committed or rolled back following the same rules as regular transactions, with no option for manual intervention from other sessions, in MSSQL distributed transactions are used to coordinate transactions using Linked Servers.
sql.distributedis a alias forsql.beginDistributedConnection Pool
No connection will be made until a query is made.
If a connection is closed or not able to connect it will only retry it if no other connection is currently available to be used, this enables Bun to run even if not all connections are able to established minimizing downtimes. Bun will open as many connections until max number of connections is reached. By default max is 10. This can be changed by setting max in the Bun.sql() call. Example - Bun.sql({ max: 20 }).
Differences from
postgrespackage:1 - Error code
UNSAFE_TRANSACTIONisERR_POSTGRES_UNSAFE_TRANSACTION2 -
postgrespackage will accept 0 inmaxvalue, we will throw a error, the default value will be the same 10,postgreswill use 0 with means hanging when trying to do a query.3 -
postgresis conservative and will lazy open each connection only if enough concurrency is achieved, untilmaxis reached,Bun.sqltry to keep the pool full (untilmaxis reached) when possible after the first query is called or when retries are needed to maximize throughput.4 - Features present in
postgresand not inBun.sql:sql.readable()sql.writable()sql.cursorsql.filesql.simplesql.listensql.notifysql.subscribesql.unsafesql.preparein transactions seesql.beginDistributedoptions.typesoptions.transform