#flipcode

#flipcode
Welcome to the chatterbox... 
#flipcode forumspace!

Browsing General Programming

locking in SQL?


 




 
Bramz (9)locking in SQL? - 2007-03-06 14:50:23
Avatar of user Bramz
Registered: unknown
Posts: 17

Hi folks,

Just for the sake of using this lonely forum once more, I'll put my SQL question here.

Say I have a table foo with two simple columns id and bar. id is an auto_increment integer, and bar is a string. Now, what I want to do is to lookup the id given bar value, and if it not exists to add a new record and return id of that new record.

Either I do this in one query (how?) and if I can't I must use at least two queries using some locking mechanism (in order not to end up the same bar twice).

Anyone who can shed some light on my rusty SQL knowledge?

Yours truly,

Bramz

Dirtysouthafrican (2)Re: locking in SQL? - 2007-03-06 15:38:53
Avatar of user Dirtysouthafrican
Registered: unknown
Posts: 312

You could wrap your queries in a


BEGIN;

blah blah blah

COMMIT;

Just looking at the mysql reference, you would then need a temporary var


SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price=@min_price OR price=@max_price;

Putting the two together, I suspect


BEGIN;
SELECT @foo_var := foo FROM mytable WHERE bar = `something`;
IF @foo_var IS NOT NULL
  ...do your thing
ELSE
  ...do your other thing
COMMIT;

The mysql api (say, from php) will then tell you the id generated by the last inser (if there was one). To wit:


int mysql_insert_id (resource [link_identifier])

mysql_insert_id() returns the ID generated for an AUTO_INCREMENT column by the previous INSERT query using the given link_identifier. If link_identifier isn't specified, the last opened link is assumed.

mysql_insert_id() returns 0 if the previous query does not generate an AUTO_INCREMENT value. If you need to save the value for later, be sure to call mysql_insert_id() immediately after the query that generates the value.

   Note: The value of the MySQL SQL function LAST_INSERT_ID() always contains the most recently generated AUTO_INCREMENT value, and is not reset between queries.
Bramz (9)Re: locking in SQL? - 2007-03-06 15:57:50
Avatar of user Bramz
Registered: unknown
Posts: 17

Forgive me my lack of SQL knowledge.

This BEGIN COMMIT stuff is a transaction right? Does this act atomicly towards other "clients"? Because I don't want that another client does SELECT @foo_var := foo FROM mytable WHERE bar = `something`; before I did the appropriate action.

This has nothing to do with stored procedures, right?

Dirtysouthafrican (2)Re: locking in SQL? - 2007-03-06 15:59:29
Avatar of user Dirtysouthafrican
Registered: unknown
Posts: 312

Yes, it is atomic. You could have a transaction that is shared also, but I believe BEGIN COMMIT is blocking.

Nothing to do with stored procedures, which I know nothing about.

This assumes your tables support transactions (e.g. InnoDB).. otherwise, use


lock tables mytablename;
unlock tables;
Bramz (9)Re: locking in SQL? - 2007-03-06 16:12:58
Avatar of user Bramz
Registered: unknown
Posts: 17

OK, thanks a lot.

I've figured out how to do it with locks by now, but transactions seem cooler ;) OK, I know that's not a good enough reason to prefer them, but somehow it sounds more database-ish. I'll have to learn a bit more about transactions I guess.

Thanks

Dirtysouthafrican (2)Re: locking in SQL? - 2007-03-06 16:20:15
Avatar of user Dirtysouthafrican
Registered: unknown
Posts: 312

I think it all depends on how greedy your queries are. Transaction safe tables are more optimized and are generally safer.

Bramz (9)Re: locking in SQL? - 2007-03-06 16:33:02
Avatar of user Bramz
Registered: unknown
Posts: 17

Turns out there's a much simplier solution to my problem: UNIQUE =) If I set bar to be unique, I can INSERT (which may possibly fail) before I select, avoiding the race condition.

In my case, the constraint to be unique is actually about two columns, but that seems to be no problem because you can set a UNIQUE KEY over multiple columns at once. Huray. =)

Dirtysouthafrican (2)Re: locking in SQL? - 2007-03-06 17:03:19
Avatar of user Dirtysouthafrican
Registered: unknown
Posts: 312

Yeah this is how I solved the problem on this site's codebase. However I wasn't sure if that's what you wanted.


 
You need to log in in order to reply to this topic.
generated:August 28, 2008, 12:04 am
Generated on August 28, 2008, 12:04 am



© 2007 Lionel Brits

This page validates as XHTML 1.1 RSS 2.0 posts


Theme © 2006 Lionel Brits