@@ -293,42 +293,94 @@ public final class PostgresClient: Sendable, ServiceLifecycle.Service {
293293 return ConnectionAndMetadata ( connection: connection, maximalStreamsOnConnection: 1 )
294294 }
295295 }
296-
297296
298297 /// Lease a connection for the provided `closure`'s lifetime.
299298 ///
300299 /// - Parameter closure: A closure that uses the passed `PostgresConnection`. The closure **must not** capture
301300 /// the provided `PostgresConnection`.
302301 /// - Returns: The closure's return value.
302+ @_disfavoredOverload
303303 public func withConnection< Result> ( _ closure: ( PostgresConnection ) async throws -> Result ) async throws -> Result {
304304 let connection = try await self . leaseConnection ( )
305305
306306 defer { self . pool. releaseConnection ( connection) }
307307
308308 return try await closure ( connection)
309309 }
310-
310+
311+ #if compiler(>=6.0)
311312 /// Lease a connection for the provided `closure`'s lifetime.
312- /// A transation starts with call to withConnection
313- /// A transaction should end with a call to COMMIT or ROLLBACK
314- /// COMMIT is called upon successful completion and ROLLBACK is called should any steps fail
315313 ///
316314 /// - Parameter closure: A closure that uses the passed `PostgresConnection`. The closure **must not** capture
317315 /// the provided `PostgresConnection`.
318316 /// - Returns: The closure's return value.
319- public func withTransaction< Result> ( _ process: ( PostgresConnection ) async throws -> Result ) async throws -> Result {
320- try await withConnection { connection in
321- try await connection. query ( " BEGIN; " , logger: self . backgroundLogger)
322- do {
323- let value = try await process ( connection)
324- try await connection. query ( " COMMIT; " , logger: self . backgroundLogger)
325- return value
326- } catch {
327- try await connection. query ( " ROLLBACK; " , logger: self . backgroundLogger)
328- throw error
329- }
317+ public func withConnection< Result> (
318+ isolation: isolated ( any Actor ) ? = #isolation,
319+ // DO NOT FIX THE WHITESPACE IN THE NEXT LINE UNTIL 5.10 IS UNSUPPORTED
320+ // https://github.com/swiftlang/swift/issues/79285
321+ _ closure: ( PostgresConnection ) async throws -> sending Result) async throws -> sending Result {
322+ let connection = try await self . leaseConnection ( )
323+
324+ defer { self . pool. releaseConnection ( connection) }
325+
326+ return try await closure ( connection)
327+ }
328+
329+ /// Lease a connection, which is in an open transaction state, for the provided `closure`'s lifetime.
330+ ///
331+ /// The function leases a connection from the underlying connection pool and starts a transaction by running a `BEGIN`
332+ /// query on the leased connection against the database. It then lends the connection to the user provided closure.
333+ /// The user can then modify the database as they wish. If the user provided closure returns successfully, the function
334+ /// will attempt to commit the changes by running a `COMMIT` query against the database. If the user provided closure
335+ /// throws an error, the function will attempt to rollback the changes made within the closure.
336+ ///
337+ /// - Parameters:
338+ /// - logger: The `Logger` to log into for the transaction.
339+ /// - file: The file, the transaction was started in. Used for better error reporting.
340+ /// - line: The line, the transaction was started in. Used for better error reporting.
341+ /// - closure: The user provided code to modify the database. Use the provided connection to run queries.
342+ /// The connection must stay in the transaction mode. Otherwise this method will throw!
343+ /// - Returns: The closure's return value.
344+ public func withTransaction< Result> (
345+ logger: Logger ,
346+ file: String = #file,
347+ line: Int = #line,
348+ isolation: isolated ( any Actor ) ? = #isolation,
349+ // DO NOT FIX THE WHITESPACE IN THE NEXT LINE UNTIL 5.10 IS UNSUPPORTED
350+ // https://github.com/swiftlang/swift/issues/79285
351+ _ closure: ( PostgresConnection ) async throws -> sending Result) async throws -> sending Result {
352+ try await self . withConnection { connection in
353+ try await connection. withTransaction ( logger: logger, file: file, line: line, closure)
354+ }
355+ }
356+ #else
357+
358+ /// Lease a connection, which is in an open transaction state, for the provided `closure`'s lifetime.
359+ ///
360+ /// The function leases a connection from the underlying connection pool and starts a transaction by running a `BEGIN`
361+ /// query on the leased connection against the database. It then lends the connection to the user provided closure.
362+ /// The user can then modify the database as they wish. If the user provided closure returns successfully, the function
363+ /// will attempt to commit the changes by running a `COMMIT` query against the database. If the user provided closure
364+ /// throws an error, the function will attempt to rollback the changes made within the closure.
365+ ///
366+ /// - Parameters:
367+ /// - logger: The `Logger` to log into for the transaction.
368+ /// - file: The file, the transaction was started in. Used for better error reporting.
369+ /// - line: The line, the transaction was started in. Used for better error reporting.
370+ /// - closure: The user provided code to modify the database. Use the provided connection to run queries.
371+ /// The connection must stay in the transaction mode. Otherwise this method will throw!
372+ /// - Returns: The closure's return value.
373+ public func withTransaction< Result> (
374+ logger: Logger ,
375+ file: String = #file,
376+ line: Int = #line,
377+ _ closure: ( PostgresConnection ) async throws -> Result
378+ ) async throws -> Result {
379+ try await self . withConnection { connection in
380+ try await connection. withTransaction ( logger: logger, file: file, line: line, closure)
330381 }
331382 }
383+ #endif
332384
333385 /// Run a query on the Postgres server the client is connected to.
334386 ///
0 commit comments