Package: libdbi-ruby1.8
Version: 0.0.23-2+3.2.5
Severity: normal
Tags: patch
Hello,
Consider the following test:
#!/usr/bin/ruby
require 'dbi'
second_transaction = $*.first && $*.first == '1' ? true : false
@db = DBI.connect 'DBI:Pg:test'
@db['AutoCommit'] = false
if @db.select_all("SELECT tablename FROM pg_tables " \
"WHERE schemaname = 'public' AND tablename = 'test'").size == 1
@db.do 'DROP TABLE public.test'
end
@db.do <<EOF
CREATE TABLE public.test (
id INTEGER NOT NULL
);
EOF
def newId(id)
@db.transaction { |db|
puts "inserting `#{id}' into public.test"
db.do('INSERT INTO public.test VALUES($1)', id)
return 42
}
end
newId(100)
exit unless second_transaction
puts "executing empty transaction"
@db.transaction { |db| }
#!/usr/bin/ruby
require 'dbi'
@db = DBI.connect 'DBI:Pg:test'
rows = @db.select_all('SELECT * FROM public.test')
puts "#{rows.size} rows in public.test"
rows.each { |r|
puts "id: #{r.first}"
}
$./transaction_return && ./check
inserting `100' into public.test
0 rows in public.test
Without execution of the second transaction, commit isn't done.
$./transaction_return 1 && ./check
inserting `100' into public.test
executing empty transaction
1 rows in public.test
id: 100
When the second transaction is executed, INSERT done in the previous
transaction is commited. From this it can be concluded that neither commit
nor rollback is done when `return' is executed from within a transaction
method block.
I'm attaching a patch that ensures that commit happens even if control
is transferred out of the transaction method. The patch also enhances
transaction method to return value returned by block when it could be used
in the calling code (i.e. when no exception happened and no return statement
executed).
-- System Information:
Debian Release: testing/unstable
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.4.27-2-k7
Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R (charmap=KOI8-R)
Versions of packages libdbi-ruby1.8 depends on:
ii libruby1.8 1.8.2-7sarge2 Libraries necessary to run Ruby 1.
libdbi-ruby1.8 recommends no packages.
-- no debconf information
--- /usr/lib/ruby/1.8/dbi/dbi.rb 2006-04-07 14:11:08.000000000 +1200
+++ dbi.rb 2006-08-04 19:59:02.000000000 +1200
@@ -746,11 +746,16 @@
commit
begin
- yield self
+ ret = yield self
commit
+ done = true
+ ret
rescue Exception
rollback
+ done = true
raise
+ ensure
+ commit unless done
end
end