The rails transaction implementation does not make use of savepoints (or similar technologies) that are used by databases to support nested transactions.
True nested transactions are not supoprted by the databases themselves.
example:
begin -- starts transaction 1
begin -- start transaction 2
insert into something (foo) values ('bar');
commit -- ends transaction 1
rollback -- is ignored
The first commit
or rollback
always closes the out-most transaction.
There is a way how databases actually can do the nesting. this would use the before mentioned savepoints. example
begin -- starts transaction 1
savepoint foo -- starts "transaction" 2
insert into something (foo) values ('bar');
release -- commit for transaction 2
rollback -- roll back the data of the savepoint and everything else within transaction 1
You can nest as many savepoints as you want within each other, as long as a transaction is open.
For rails itself there is a catch though: The functions create and similar wrap themselves within an transaction. so your first example produces the follwing sql
begin -- transaction.do
begin -- Client.create
insert into clients ( name ) values ('Pavel') -- Client.create
commit -- Client.create, closes the out-most transaction
begin -- transaction.do
begin -- Client.create
insert into clients ( name ) values ('Elena') -- Client.create
commit -- Client.create, closes the out-most transaction
So your Exception just arrives to late.
You can patch this issue, but you have to do it for every connection adapter.
PS:
You might be confused by the --
within the sql. Those are single line comments in mysql..