Thread: Performance question: Commit or rollback?

Performance question: Commit or rollback?

From
Chris Angelico
Date:
Some of my code involves transactions which will not have significant
effect on the database. It might be a read-only transaction (possibly
declared as one, but possibly not), or perhaps a completely empty
transaction - I have a framework that will always open a transaction,
then call on other code, and then complete the transaction at the
bottom.

In these instances, is it better to commit or to rollback? Are there
performance penalties to either option?

Similarly, what about when the first action in a transaction puts it
in an error state? Is it better to commit (which should have no effect
- nothing succeeded) or to roll back?

I could test these things experimentally, but am afraid I'll skew my
results based on the data I use. Hoping that somebody here knows for
certain - there does seem to be a wealth of expertise here.

Chris Angelico

Re: Performance question: Commit or rollback?

From
Chris Travers
Date:
On Sat, Dec 17, 2011 at 6:53 PM, Chris Angelico <rosuav@gmail.com> wrote:
> Some of my code involves transactions which will not have significant
> effect on the database. It might be a read-only transaction (possibly
> declared as one, but possibly not), or perhaps a completely empty
> transaction - I have a framework that will always open a transaction,
> then call on other code, and then complete the transaction at the
> bottom.
>
> In these instances, is it better to commit or to rollback? Are there
> performance penalties to either option?

I do not believe there are performance penalties for either.  All
commit or rollback does is determine visibility of changes made.

Best Wishes,
Chris Travers

Re: Performance question: Commit or rollback?

From
Chris Angelico
Date:
On Sun, Dec 18, 2011 at 2:02 PM, Chris Travers <chris.travers@gmail.com> wrote:
> I do not believe there are performance penalties for either.  All
> commit or rollback does is determine visibility of changes made.

Thanks. (And thanks for the incredibly quick response!)

My framework has a "read-only mode" (determined by user-level access),
in which it begins a read-only transaction. At the end of it, I
currently have it rolling the transaction back (to make absolutely
sure that no changes will be made), but was concerned that this might
place unnecessary load on the system. I'll stick with rolling back,
since it's not going to hurt!

Chris Angelico

Re: Performance question: Commit or rollback?

From
vinny
Date:
On Sun, 2011-12-18 at 14:05 +1100, Chris Angelico wrote:
> On Sun, Dec 18, 2011 at 2:02 PM, Chris Travers <chris.travers@gmail.com> wrote:
> > I do not believe there are performance penalties for either.  All
> > commit or rollback does is determine visibility of changes made.
>
> Thanks. (And thanks for the incredibly quick response!)
>
> My framework has a "read-only mode" (determined by user-level access),
> in which it begins a read-only transaction. At the end of it, I
> currently have it rolling the transaction back (to make absolutely
> sure that no changes will be made), but was concerned that this might
> place unnecessary load on the system. I'll stick with rolling back,
> since it's not going to hurt!
>
> Chris Angelico
>

The actual rollback won't hurt as long as you have not made any
modificatons to any records. But opening the transaction could have side
effects for other processes that want to modiy the records that you want
to protect in your read-only transaction.

How about using a databaseuser that has it's create/update/delete rights
revoked? That will cause an error if the supposedly read-only routine
does try to change data.


Re: Performance question: Commit or rollback?

From
Chris Angelico
Date:
On Sat, Dec 24, 2011 at 11:46 PM, vinny <vinny@xs4all.nl> wrote:
> The actual rollback won't hurt as long as you have not made any
> modificatons to any records. But opening the transaction could have side
> effects for other processes that want to modiy the records that you want
> to protect in your read-only transaction.
>
> How about using a databaseuser that has it's create/update/delete rights
> revoked? That will cause an error if the supposedly read-only routine
> does try to change data.

The readonly-ness of the session is defined based on information
stored in the database, so that would entail the cost of
re-authenticating. Also, we want to minimize debugging time by having
both read-only and read-write access use almost exactly the same code
and DB access, meaning that we should not need to test every module in
every mode.

ChrisA

Re: Performance question: Commit or rollback?

From
vinny
Date:
On Sat, 2011-12-24 at 23:49 +1100, Chris Angelico wrote:
> On Sat, Dec 24, 2011 at 11:46 PM, vinny <vinny@xs4all.nl> wrote:
> > The actual rollback won't hurt as long as you have not made any
> > modificatons to any records. But opening the transaction could have side
> > effects for other processes that want to modiy the records that you want
> > to protect in your read-only transaction.
> >
> > How about using a databaseuser that has it's create/update/delete rights
> > revoked? That will cause an error if the supposedly read-only routine
> > does try to change data.
>
> The readonly-ness of the session is defined based on information
> stored in the database, so that would entail the cost of
> re-authenticating.

Yes you would have to re-authenticate, you'd have to weigh the time-cost
of that that against any performance hits the transaction might cause.

> Also, we want to minimize debugging time by having
> both read-only and read-write access use almost exactly the same code
> and DB access, meaning that we should not need to test every module in
> every mode.

So, your read-only mode is basically a flag that forces your code to
always issue a rollback at the end, instead of a commit for read/write
mode.

I find that a bit scary. :-)

regard,
Vincent.




Re: Performance question: Commit or rollback?

From
Chris Angelico
Date:
On Sun, Dec 25, 2011 at 12:00 AM, vinny <vinny@xs4all.nl> wrote:
> So, your read-only mode is basically a flag that forces your code to
> always issue a rollback at the end, instead of a commit for read/write
> mode.
>
> I find that a bit scary. :-)

It's three things:

1) BEGIN TRANSACTION READ ONLY instead of BEGIN TRANSACTION
2) A high level flag that tells the PHP code that it ought not to change things
3) ROLLBACK instead of COMMIT

ChrisA

Re: Performance question: Commit or rollback?

From
Darren Duncan
Date:
Chris Angelico wrote:
> On Sat, Dec 24, 2011 at 11:46 PM, vinny <vinny@xs4all.nl> wrote:
>> How about using a databaseuser that has it's create/update/delete rights
>> revoked? That will cause an error if the supposedly read-only routine
>> does try to change data.
>
> Also, we want to minimize debugging time by having
> both read-only and read-write access use almost exactly the same code
> and DB access, meaning that we should not need to test every module in
> every mode.

You can do it correctly while reusing all of your code; you just have different
arguments at connect time and otherwise your code uses the connection handle in
the same way afterwards.  Its fine to have flags in the app so the app just
tries acceptable things, but privileges in the database are the only way to
actually be safe and resilient against accidental changes. -- Darren Duncan

Re: Performance question: Commit or rollback?

From
Chris Travers
Date:
On Sat, Dec 24, 2011 at 11:34 AM, Darren Duncan <darren@darrenduncan.net> wrote:

>
>
> You can do it correctly while reusing all of your code; you just have
> different arguments at connect time and otherwise your code uses the
> connection handle in the same way afterwards.  Its fine to have flags in the
> app so the app just tries acceptable things, but privileges in the database
> are the only way to actually be safe and resilient against accidental
> changes. -- Darren Duncan

Agreed.  Roles in the db are important (we use them extensively in
LedgerSMB).  However here is a case where it doesn't work so well:

Suppose I want to run read-write test cases against a production
database to look for things that are wrong but we want to be
mathematically sure that the test cases do not commit data to the
database.

So I don't entirely know the best way to do this in other languages,
but here is what we did in Perl:

1) Our application normally uses DBI (and DBD::Pg).
2)  We have a special module (LedgerSMB::DBTest) which basically
exposes the portions of the DBI/DBD::Pg interface we are using, but
lies to the higher levels about committing.  Basically it returns
true, but does nothing database-wise, providing the appearance of a
consistent set of changes but in fact the changes are still to be
rolled back.
3)  In our test case scripts, we switch out the DBI database handles
with instances of LedgerSMB::DBTest.

This works well because it is fails safely.  If we omit something from
the DBTest module, our code will error.  If we have test cases that
depend on some transactions committing and others rolling back, we
have to order the test cases appropriately or the test cases fail.  In
other words, the worst we can get are test case failures, not spurious
commits, and the changes necessary to make this happen are in the test
case files themselves.  This makes it easy to verify.

Best Wishes,
Chris Travers