Skip to content

Commit

Permalink
Merge pull request #463 from ejoubaud/fix-transaction-leak
Browse files Browse the repository at this point in the history
Fix transaction leak on early break/return
  • Loading branch information
larskanis committed Jun 15, 2022
2 parents 26cd0f7 + 48bc9b2 commit 217536e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
10 changes: 7 additions & 3 deletions lib/pg/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,20 @@ class << self
# and a +COMMIT+ at the end of the block, or
# +ROLLBACK+ if any exception occurs.
def transaction
rollback = false
exec "BEGIN"
res = yield(self)
rescue Exception
rollback = true
cancel if transaction_status == PG::PQTRANS_ACTIVE
block
exec "ROLLBACK"
raise
else
exec "COMMIT"
res
ensure
unless rollback
exec "COMMIT"
res
end
end

### Returns an array of Hashes with connection defaults. See ::conndefaults
Expand Down
26 changes: 26 additions & 0 deletions spec/pg/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,32 @@
end
end

it "commits even if the block includes an early break/return" do
# abort the per-example transaction so we can test our own
@conn.exec( 'ROLLBACK' )

@conn.exec( "CREATE TABLE pie ( flavor TEXT )" )

begin
@conn.transaction do
@conn.exec( "INSERT INTO pie VALUES ('rhubarb'), ('cherry'), ('schizophrenia')" )
# a prior version would neither commit nor rollback when the block included an early break/return
break
end

# if the previous transaction committed, the result should be visible from another conn/transaction
@conn2 = PG.connect(@conninfo)
begin
res = @conn2.exec( "SELECT * FROM pie" )
expect( res.ntuples ).to eq( 3 )
ensure
@conn2.close
end
ensure
@conn.exec( "DROP TABLE pie" )
end
end

it "passes the connection to the block and returns the block result" do
# abort the per-example transaction so we can test our own
@conn.exec( 'ROLLBACK' )
Expand Down

0 comments on commit 217536e

Please sign in to comment.