Could someone explain this (transaction-related)?

Hi all,

I was testing, and found a nested transaction (which I know is bad), and
there’s something I don’t understand. If an exception occurs during a
transaction, it is supposed to roll back. In a nested transaction,
where an exception is raised out of the ‘inner’ transaction, this
doesn’t occur. However, if I catch the exception and manually call
‘connection.rollback_db_transaction’, it works, e.g.:

Applicant.transaction do
a = Applicant.find(1)
begin
Applicant.transaction do
a.first_name = ‘bar’
a.save!
raise “Foo” # This does not roll back the transaction…
end
rescue
Applicant.connection.rollback_db_transaction # But this will
end
end

I don’t see why it makes a difference if I call rollback_db_transaction
in rescue. I thought that happened automatically. Looking at the
source, I can’t see where it happens.

Thanks if anyone can clear this up for me. I am trying to use
transactional fixtures for all my tests, and this is a sticking point.
If I can understand this, I think I can convert them all.

On 1 May 2008, at 22:39, Brian H. wrote:

Rails doesn’t support nested transactions, so only the outer one is
actually doing anything, by rescuing the exception you are preventing
rails from doing the rollback.

Fred