Forum: Ruby Database Transactions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ccfe7d097475a32dc3ff78d6fc42c852?d=identicon&s=25 listrecv (Guest)
on 2005-11-15 09:28
(Received via mailing list)
ActiveRecord's standard procedure for transactions is to send a block,
and throw an exception to roll it back (
http://api.rubyonrails.com/classes/ActiveRecord/Tr...
).  I found this rather uncomfortable.  I'd like to be able to begin
transactions, commit them, or roll them back from within (fairly)
complex control structures - and having to do everything within a
block, with one way out, is no good.

Any suggestions?

PS This question concerns ActiveRecord, an O/R mapper which can be used
for lots of things.  It's _not_ a _rails_ questions (what's rails???)
3a83969376c805ef5b6042191fdb0ff3?d=identicon&s=25 Andreas S. (andreas)
on 2005-11-15 12:34
listrecv wrote:
> ActiveRecord's standard procedure for transactions is to send a block,
> and throw an exception to roll it back (
> http://api.rubyonrails.com/classes/ActiveRecord/Tr...
> ).  I found this rather uncomfortable.  I'd like to be able to begin
> transactions, commit them, or roll them back from within (fairly)
> complex control structures - and having to do everything within a
> block, with one way out, is no good.

You can start/commit/rollback transactions manually
(ActiveRecord::Base.connection.start_transaction, IIRC). Though I don't
see why using a block should be a problem for your control structure.
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 bob.news (Guest)
on 2005-11-15 13:04
(Received via mailing list)
Andreas Schwarz wrote:
> listrecv wrote:
>> ActiveRecord's standard procedure for transactions is to send a
>> block, and throw an exception to roll it back (
>>
http://api.rubyonrails.com/classes/ActiveRecord/Tr...
>> ).  I found this rather uncomfortable.  I'd like to be able to begin
>> transactions, commit them, or roll them back from within (fairly)
>> complex control structures - and having to do everything within a
>> block, with one way out, is no good.
>
> You can start/commit/rollback transactions manually
> (ActiveRecord::Base.connection.start_transaction, IIRC). Though I
> don't see why using a block should be a problem for your control
> structure.

+1

Using the block is definitely superior and less error prone.  Hint: you
can call methods from the block. :-)

Kind regards

    robert
Ccfe7d097475a32dc3ff78d6fc42c852?d=identicon&s=25 listrecv (Guest)
on 2005-11-15 18:09
(Received via mailing list)
Okay, I'll trust you guys know better than I do.
How do I do this with a block?

  def signup
  # It gets a little tricky, since we want to create either both an
account and user or neither

    @account = Account.new(params[:account])
    @user = User.new(params[:user])
    @user.login = @account.code	# For now, we keep a 1-to-1 between
these
    @user.real_name = @account.name

    begin
	    # TODO begin transaction
	    if (@user.valid?)
	    	@account.user = @user	# Don't assign until we know it is valid -
ActiveRecord sometimes saves on assign
	    	if (@account.valid?)	# We need to do this in two steps, since
@account won't be valid without a user
	    		@user.save!
	    		@account.save!
	    		# TODO end transaction
	    		flash[:notice] = 'Account added.'
      			redirect_to :action => 'list'
      			return
    		end
	    end
	    # TODO rollback transaction
     	render :action => 'new'
	# TODO rescue exceptions
	end
  end


(Okay, I admit it, yes, this is part of a rails app...)
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 bob.news (Guest)
on 2005-11-15 18:27
(Received via mailing list)
listrecv@gmail.com wrote:
> Okay, I'll trust you guys know better than I do.
> How do I do this with a block?

http://wiki.rubyonrails.com/rails/pages/HowToUseTransactions

>     begin
>       redirect_to :action => 'list'
>       return
>     end
>     end
>     # TODO rollback transaction

Why do you want to do a rollback here?  There is no rescue clause nor
any
indication that an error has occurred.  If you use a block then you
don't
need explicit commit and rollback.  It's handled in the method that
receives the block (#transaction).

>      render :action => 'new'
> # TODO rescue exceptions
> end
>   end
>
>
> (Okay, I admit it, yes, this is part of a rails app...)

I know only little about RoR so there might as well be other answers.

Kind regards

    robert
Ccfe7d097475a32dc3ff78d6fc42c852?d=identicon&s=25 listrecv (Guest)
on 2005-11-15 21:37
(Received via mailing list)
> Why do you want to do a rollback here?

It's not to catch exceptions.  It's to make sure that no account is
saved without a user or vice versa (which would happen to be very
bad...).  Especially confusing since I know AR sometimes saves
associations before we ask...
This topic is locked and can not be replied to.