Everything2
Near Matches
Ignore Exact
Full Text
Everything2

savepoint

created by C-Dawg

(thing) by C-Dawg (2.7 hr) (print)   ?   1 C! I like it! Wed Jul 05 2006 at 4:01:15

So, Mr. Banker, you're using transactions in your computer programs to protect the integrity of your data; that's good!

About transactions

Here's a quick introduction or review for those who aren't. Anytime you need to modify your database using more than one operation in sequence, you run the risk of a system or program failure occuring after you've begun but before you finish.

The canonical example, as Big Ben is well aware, is the task of moving a sum of money from one account to another. One first subtracts $X from account A, and then adds it to account B. A failure between the two steps leaves you with a sum of money missing, and nobody likes that. Thus, in SQL, one begins a transaction before the first step, and commits it after the last. The database software ensures that the net effect is either a succesful, complete movement of money, or no change at all.

And now back to savepoints

That's all wonderful, and a boon to programmers the world over. There must be a catch, right? Right. Committing a transaction is an expensive operation (in terms of time; Oracle won't send you a bill). Now let's say that before the Fed closes for the night, Ben has to put on his green visor and do a thousand such transfers. If he does them all in one transaction, he'll get home in time and the Missus won't yell at him; committing after each one will take longer and he'll be lucky if she leaves him leftovers from the dog's dinner.

Unfortunately, the ANSI committee that standardized SQL played a joke, and even Big Al couldn't talk them out of it. They said that any error that occurs inside of a transaction renders the transaction void, and the database will require a rollback. This means that if you've done 999 transfers, but then while you're trying to move $20,000 from Fred's Bank to the Bank of Ethel, the database barks at you because Fred hasn't got it, then all your work is undone and now even the kibble will be cold when you get home.

Are you destined never to get that hot pot roast with apple pie warm from the oven? Was it because you shortchanged an Assyrian rug merchant in a prior life? Well, it's not hopeless. SQL provided you a way to have your cake and eat it, too. (Cake with pot roast?)

Within a transaction, you are allowed to declare a SAVEPOINT. What this does is, it allows you later, after an error occurs, to say to the database, "Okay, I'll rollback. But only back to my savepoint!" This allows you to quickly rewrite your nightly task something like this:

Begin transaction
For each transfer to be done
    Savepoint MyBacon
    Subtract $X from A
    Add $X to B
    If there was any error
        Rollback to savepoint MyBacon
Commit transaction
Now, all your successful transfers will get committed, even if there are errors, and you only have to commit once so you can get home. Though you ought at least to make a note of Fred's overdraft for the morning crew to take care of, so you may miss the very beginning of the salad course.

That is the canonical way to use savepoints. At least, it's the only way I ever have. SQL allows more complicated setups, in that you can have more than one savepoint outstanding at a time (which is why you give it a name when you declare it), but I doubt I'll ever have a use for that.

One hint, if you're using savepoints with PostgreSQL. In a departure from the standard, PostgreSQL maintains stacks of like-named savepoints, rather than releasing[1] the current one when a new one is declared with the same name. Hence the above code would tend to accumulate many of them for no reason. Therefore I actually put a "Release savepoint MyBacon" statement at the end of the loop.

[1] There is a related SQL command called RELEASE, which causes a named savepoint to be destroyed. In the case of PostgreSQL, RELEASEing a savepoint removes the most recently declared one with the given name, restoring visibility to the next most recently declared (and unreleased) savepoint with the same name. Why they did it that way, and why you'd want to take advantage of it, is beyond me.

Well, the reason they did it that way is so that if a stored procedure called during your transaction unknowingly (to you) used the same name for its savepoint as you did for yours, it wouldn't mess with yours. Assuming it was released before the procedure returned, of course.


printable version
chaos

I play video games for a living PostgreSQL Everytime I get XP, I feel like I have to save my game Shiloh
Oracle Ben Bernanke acid Green Salad with Goat Cheese, Walnuts and Hot Onions
Fluke commit rollback Transaction
July 5, 2002 March 3, 2006 P
Y'know, if you log in, you can write something here, or contact authors directly on the site. Create a New User if you don't already have an account.
  Epicenter
Login
Password

password reminder
register

Everything2 Help

Cool Staff Picks
Things you could have written:
1001 Ways to Beat the Draft
Hands
Jesus and faggots
The White Butterfly
The problems of the modern west
An example of Atari 2600 source code
Dracula
It is my nature to covet
Fuel cell
Little Anthony and the Imperials
Touch the Puppy
The Simpsons
County Lines
New Writeups
cryforhelp
Major dictionaries of the world(review)
Glowing Fish
The Uncanny X-Men and the New Teen Titans(thing)
WolfKeeper
Launch loop(idea)
TendoKing
Katana(person)
Wuukiee
Highly ornamental cultivars of brambles still have as many thorns as their wild counterparts(idea)
TheDeadGuy
Editor Log: May 2008(log)
everyday j.Lo
pray do not molest them(thing)
ammie
Bands Who Take Their Names from Eighteenth-century English Poetry and Prose(idea)
shaogo
Under My Thumb(review)
ammie
Rock On(person)
The Custodian
The Dresden Files(thing)
Ouzo
PETA becomes you, a proposed future(fiction)
Ereneta
Stone Soup, Part Two(fiction)
jjen
Sorrier than I ever thought I would be(personal)
locke baron
Moskva class antisubmarine cruiser(thing)
This page courtesy of The Everything Development Company