![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I have created the following table: CREATE TABLE public.books ( name VARCHAR PRIMARY KEY ); And I have started a transaction in 2 different clients (for example, 2 different SQL windows in PgAdmin), so: START TRANSACTION; Then, I have noticed that, if I execute: INSERT INTO public.books VALUES ('Test Book'); on both clients, the second one hangs until I commit or rollback the other transaction. So, I wish to know: 1)Why does this happen? Aren't 2 transactions mutually independent? 2)Is there a way to execute the 2 INSERT commands at the same time? And if not, what could I do to prevent the hanging of the second client? I'm using PostgreSQL 8.1.4. |
#3
| |||
| |||
|
|
My question: Why would you want PostgreSQL to behave otherwise? What is your real problem? |
#4
| |||
| |||
|
|
Well, I am developing a software which should manage a book database. If the user wants to add a book, the program asks the book name, starts a transaction and adds the book to the "books" table. I said "starts the transaction" because the process of adding a book is quite long, and the user must insert a lot of data, and those data will be used by another program, so every book must have all of its data inserted: if I didn't start a transaction, and if the user's PC turned off just after inserting the book in its table, the book would appear to exist, but its data would be incomplete. On the contrary, if I start a transaction and two users insert the same book, the second one's client hangs... and this happens because the primary key can "see" inside each still uncommitted transaction. |
#5
| |||
| |||
|
|
Here's my idea how to do it: - Do not use the book name as primary key. It may change (e.g., if somebody has made a typo). How about the ISBN? - Have the user enter the primary key. - Check with a select if the book already exists. If yes, error out. - Have the user enter all the data for the book. Cache them in your application and check them for sanity (possibly using database queries). - As soon as the user is done, start a transaction and add the book to the database. Then commit. Drawback: in the unlikely event that somebody else has made a conflicting entry in the meantime, the transaction will fail AFTER the user has gone through the tedious process of entering all the data. Advantage: You don't have to hold locks for a long time, which is always a bad idea. |
|
Try to avoid transactions that take a long time, especially ones that include user interaction - what if the user walks away or dies while entering the book? How do you detect that and cancel the transaction? |
#6
| |||
| |||
|
|
Drawback: in the unlikely event that somebody else has made a conflicting entry in the meantime, the transaction will fail AFTER the user has gone through the tedious process of entering all the data. Advantage: You don't have to hold locks for a long time, which is always a bad idea. Thank you a lot for your very, very valuable advice. I'll try to do as you told me. I'm quite new to DB servers, so I still have some problems when working with transactions, locks, and so on... |
|
Try to avoid transactions that take a long time, especially ones that include user interaction - what if the user walks away or dies while entering the book? How do you detect that and cancel the transaction? In my situation, this won't happen! ^______^ It will be used by less than 10 people... Anyway, thank you for the advice. |
#7
| |||
| |||
|
|
The database is supposed to take care about the details of making transactions and so on work. You do need to know the basics, though. |
|
The database will keep its tables consistent (free of half-entered records that can cause havoc) but you have to tell it what parts belong together, and you want to transfer the data close together as much as possible. |
|
I'd probably consider doing a query for the ISBN as soon as it is entered and at least notify the user that such an ISBN already exists. Being responsive to the user is useful, but don't let the application become bogged down and slow because of the many queries it does. Once the entry is completed and submitted by the user, do locking, full checking, and committing to the database. Try to avoid transactions that take a long time, especially ones that include user interaction - what if the user walks away or dies while entering the book? How do you detect that and cancel the transaction? In my situation, this won't happen! ^______^ It will be used by less than 10 people... Anyway, thank you for the advice. Don't say ``won't happen'', because it will. I know from experience that even one person other than you can already trigger all sorts of ``can't happen'' situations. The less experienced and more ``user'' a user is the more likely s/he is to trigger that sort of thing. You need to spend some thought on how you will be solving that problem already, even if you feel you don't want to actually solve it right now. Plan for it anyway. |
![]() |
| Thread Tools | |
| Display Modes | |
| |