Subject | Re: Getting a unique value from a generator |
---|---|
Author | Adam |
Post date | 2005-05-12T23:47:16Z |
Hi Peter,
--- In firebird-support@yahoogroups.com, "Peter Ypenburg"
<PeterY@B...> wrote:
Ah, I can see your problem already.
Consider this scenario:
User1
1. Increments Generator
2. Gets the number 1 back, so he is "safe"
User 2
1. Increments Generator
2. Gets the number 2 back, but before he can "undo" the increment,
someone trips over the power cable and so the decrement is never run.
User 1
1. Finishes laughing at user 2 for falling over, quits the program
and the Generator is decremented, (only back to value 1 though).
So now your lock is on. I am sure there are other ways to achieve
this but as you can see it is not a safe "gate".
As Michael pointed out (correctly), Generators are transaction
independent. This means that even though User 2's transaction will
roll back, the generator call will NOT.
Here is a better way of achieving your lock. I have used it now for
about 6 months across hundreds of customers and it has NEVER failed
(and you would shake your head if you saw some of the hardware the
poor thing has to run on).
Create a table
ExportLock
(
InUse Char(1)
)
Insert into ExportLock(InUse) values ('F');
Commit;
Now modify your programs
Then instead of calling the generator, run the query. Put it in its
own transaction (Read_Committed) and do NOT commit it.
Update ExportLock set InUse = 'T';
But how can this work you ask?
When User 1 executes this line, the record is locked until the
transaction is committed.
When User 2 attempts to execute this line, they get an exception (if
READ_COMMITTED). Your application can then respond to this exception
with a meaningful error message.
When User 1 has finished, commit or rollback the transaction.
Now, our method is more sophisticated again. We have another table
that stores the current user so that the error message says
that "Peter is currently using this." etc.
Hope that helps
Adam
--- In firebird-support@yahoogroups.com, "Peter Ypenburg"
<PeterY@B...> wrote:
> We use a generator to flag a process as locked or not. I will tryand
Ah, I can see your problem already.
Consider this scenario:
User1
1. Increments Generator
2. Gets the number 1 back, so he is "safe"
User 2
1. Increments Generator
2. Gets the number 2 back, but before he can "undo" the increment,
someone trips over the power cable and so the decrement is never run.
User 1
1. Finishes laughing at user 2 for falling over, quits the program
and the Generator is decremented, (only back to value 1 though).
So now your lock is on. I am sure there are other ways to achieve
this but as you can see it is not a safe "gate".
As Michael pointed out (correctly), Generators are transaction
independent. This means that even though User 2's transaction will
roll back, the generator call will NOT.
Here is a better way of achieving your lock. I have used it now for
about 6 months across hundreds of customers and it has NEVER failed
(and you would shake your head if you saw some of the hardware the
poor thing has to run on).
Create a table
ExportLock
(
InUse Char(1)
)
Insert into ExportLock(InUse) values ('F');
Commit;
Now modify your programs
Then instead of calling the generator, run the query. Put it in its
own transaction (Read_Committed) and do NOT commit it.
Update ExportLock set InUse = 'T';
But how can this work you ask?
When User 1 executes this line, the record is locked until the
transaction is committed.
When User 2 attempts to execute this line, they get an exception (if
READ_COMMITTED). Your application can then respond to this exception
with a meaningful error message.
When User 1 has finished, commit or rollback the transaction.
Now, our method is more sophisticated again. We have another table
that stores the current user so that the error message says
that "Peter is currently using this." etc.
Hope that helps
Adam
> explain,1) FROM
>
> - The value of the generator starts of as zero.
> - The first user to execute the SQL SELECT GEN_ID(EXPORTLOCK_SEQ,
> RDB$DATABASE and gets a value of one is deemed to have the lock.they get a
> - While user 1 has the lock other users run the same SQL and if
> value bigger than one they do not have the lock and then run thefollowing
> SQL to undo their effort to get the lock i.e. SELECT GEN_ID(EXPORTLOCK_SEQ,
> -1) FROM RDB$DATABASE.value of
> - As soon as user 1 runs his SELECT GEN_ID(EXPORTLOCK_SEQ, -1) FROM
> RDB$DATABASE and all the other users have undone their locks the
> the generator should be back at zero.RDB$DATABASE
> - The next user to run SELECT GEN_ID(EXPORTLOCK_SEQ, 1) FROM
> will get a value of 1 and he is deemed to have the lock again.to get the
>
> And so the cycle continues. The client has about 150 users trying
> lock at a point in time. Somewhere along the line at the client'ssite (we
> have not been able to figure out why) this gets broken and the lockstays
> on. In our test environment we have not been able to break thelogic, the
> code is pretty well protected with try finally's and works.if this is
>
> The client does run our software using Citrix terminals. Not sure
> a possible cause although we have already had them rebuild theCitrix
> environment and yet this still happens.Pty (Ltd)
>
> Are there any flaws in the logic above?
>
>
> Peter Ypenburg
> AGM: Product Development
> Barloworld Optimus
> Tel +2711 286 1587 Fax +2711 286 1630 Cell +2782 789 9167
> www.barloworldoptimus.com
>
> Disclaimer
>
> The information transmitted is the property of Barloworld Optimus
> and is intended only for the person or entity to which it isaddressed and
> may contain confidential and/or privileged material. Statements andopinions
> expressed in this e-mail may not represent those of the company.Any review,
> retransmission, dissemination and other use of, or taking of anyaction in
> reliance upon, this information by persons or entities other thanthe
> intended recipient is prohibited. If you received this in error,please
> contact the sender immediately and delete the material from anycomputer.
>generator
> -----Original Message-----
> From: firebird-support@yahoogroups.com
> [mailto:firebird-support@yahoogroups.com] On Behalf Of Mitchell Peek
> Sent: Thursday, May 12, 2005 9:40 PM
> To: firebird-support@yahoogroups.com
> Subject: Re: [firebird-support] Getting a unique value from a
>but....
> helen or someone will reply later and tell me how wrong I am ;),
>statement at
> First, it isn't really possible for 2 users to execute the
> the *exact* same time, one has to come before the other... butanyway....
>rollback
> Generators operate outside of user transactions. Test it. A
> leaves the generator as it was whether you rollback or commit.you
> Therefore, it isn't possible for the same value to be returned if
> assume they are the only two statements going on. However, ifthere
> were a third user such that the execution occurred in thismanner....
>exact same
> user 1
>
> SELECT GEN_ID(EXPORTLOCK_SEQ, -1)
> FROM RDB$DATABASE;
>
> user 2
>
> SELECT GEN_ID(EXPORTLOCK_SEQ, 1)
> FROM RDB$DATABASE
>
> user 3
>
> SELECT GEN_ID(EXPORTLOCK_SEQ, -1)
> FROM RDB$DATABASE
>
>
> then users 1 and 3 will get the same value.
>
> Is this a possibility?
>
>
>
>
>
>
> Peter Ypenburg wrote:
>
> >Hi There,
> >
> >Is it possible for two users who run the following SQL at the
> >time (each in their own transaction) to get the same value backfrom a
> >generator. The SQL is as follows:Pty (Ltd)
> >
> >SELECT GEN_ID(EXPORTLOCK_SEQ, -1)
> >FROM RDB$DATABASE
> >
> >Thanks.
> >
> >Peter Ypenburg
> >AGM: Product Development
> >Barloworld Optimus
> >Tel +2711 286 1587 Fax +2711 286 1630 Cell +2782 789 9167
> >www.barloworldoptimus.com
> >
> >Disclaimer
> >
> >The information transmitted is the property of Barloworld Optimus
> >and is intended only for the person or entity to which it isaddressed and
> >may contain confidential and/or privileged material. Statements andAny
> opinions
> >expressed in this e-mail may not represent those of the company.
> review,action in
> >retransmission, dissemination and other use of, or taking of any
> >reliance upon, this information by persons or entities other thanthe
> >intended recipient is prohibited. If you received this in error,please
> >contact the sender immediately and delete the material from anycomputer.
> >
> >
> >
> >++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> >Visit http://firebird.sourceforge.net and click the Resources item
> >on the main (top) menu. Try Knowledgebase and FAQ links !
> >
> >Also search the knowledgebases at http://www.ibphoenix.com
> >
> >++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >
> >Yahoo! Groups Links
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
>
>
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Visit http://firebird.sourceforge.net and click the Resources item
> on the main (top) menu. Try Knowledgebase and FAQ links !
>
> Also search the knowledgebases at http://www.ibphoenix.com
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Yahoo! Groups Links