# Transaction block still sets id on model/new\_record to false on rollback

**URL:** <https://www.ruby-forum.com/t/transaction-block-still-sets-id-on-model-new-record-to-false-on-rollback/160134>\
**Category:** Rails\
**Created:** [February 12, 2009, 1:57am UTC](https://www.ruby-forum.com/t/transaction-block-still-sets-id-on-model-new-record-to-false-on-rollback/160134 "2009-02-12T01:57:45Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Farrel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/bcef8e/32.png) [@Farrel](https://www.ruby-forum.com/u/Farrel)\
**Post date:** [February 12, 2009, 1:57am UTC](https://www.ruby-forum.com/t/transaction-block-still-sets-id-on-model-new-record-to-false-on-rollback/160134/1 "2009-02-12T01:57:45Z")

</div>

I’m on Rails 2.2.2 on MySQL with InnoDB table types. I’m running into  
a wierd bug where if I have two models in a transaction and the second  
model raises an exception, the first model still has it’s ID set and  
it’s new\_record status set to false despite the row the ID is set to  
never existing.

The following is a console session showing this:

> > client\_user = new\_client\_user( :first\_name =\> nil ) # Will cause validation to fail  
> > =\> #\<ClientUser id: nil, login: “rene173744”, email\_address:  
> > “removed\_email\_address@domain.invalid”, first\_name: nil, last\_name: “Sim”, active: true\>
> 
> > establishment = new\_establishment( :brand =\> brand )  
> > =\> #\<Establishment id: nil, brand\_id: 4, name: “Pretoria GrandWest”,  
> > active: true\>
> 
> > Establishment.transaction{ establishment.save!; client\_user.save! } rescue false  
> > =\> false
> 
> > establishment.id  
> > =\> 10
> 
> > establishment.new\_record?  
> > =\> false
> 
> > client\_user.id  
> > =\> nil
> 
> > establishment.reload  
> > ActiveRecord::RecordNotFound: Couldn’t find Establishment with ID=10
> 
> > Establishment.count  
> > =\> 4

Here’s an explanation of the session:

1. I initialise a new client user, with first\_name set to nil so it  
will fail a validation
2. I then initialise a new establishment model
3. I try and save both in a transaction block. The client\_user.save!  
call raises an exception causing the block to roll back.
4. Yet establishment has an ID set to 10 and is marked as not being a  
new record.
5. As expected client\_user has no ID
6. Calling reload on establishment throws an error because the row  
does not exist
7. Counting up the actual rows we see it is below the ID assigned to  
establishment (I did this a few times, the first time the assigned ID  
was 5, then 6, then 7 etc)

Am I missing something or is this expected behaviour?

---

<div class="post-metadata">

**Author:** ![Farrel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/bcef8e/32.png) [@Farrel](https://www.ruby-forum.com/u/Farrel)\
**Post date:** [February 13, 2009, 10:13am UTC](https://www.ruby-forum.com/t/transaction-block-still-sets-id-on-model-new-record-to-false-on-rollback/160134/2 "2009-02-13T10:13:21Z")

</div>

Farrel wrote:

> I’m on Rails 2.2.2 on MySQL with InnoDB table types. I’m running into  
> a wierd bug where if I have two models in a transaction and the second  
> model raises an exception, the first model still has it’s ID set and  
> it’s new\_record status set to false despite the row the ID is set to  
> never existing.

Yes, that’s the way Transactions (now) work.

The correct way to handle this is to not proceed with  
a transaction unless all model instances being saved  
in that transaction have been validated.

The alternative is to wrap rollback\_active\_record\_state!  
blocks around the transaction for all instances being  
saved except the last.

–  
Rails Wheels - Find Plugins, List & Sell Plugins -  
[http://railswheels.com](http://railswheels.com)
