On 23/06/2009, at 7:58 AM, Kim Spears wrote:
I wish to more closely integrate these separate systems, however to do
so I need an invoice numbering routine that would ensure that no
matter
how many invoicing programs were in use each program cycle would get
the
next unique sequential number and not cause record locks.
Why the concern with locks? Locks are a normal part of application
operation and are not a problem if managed correctly. In this case a
lock would be held only for the duration of the invoice number
increment. Once that's done the lock is released and the number is
available for the next request.
It seems that a service program would be in order. The question is,
how
do I make sure only one instance of the procedure can run?
You can't. You can define the 'next number' variable as global or
static and run in a named activation group which will ensure the same
variable will be used by each invocation but this is scoped to the
job. It will not help when multiple jobs are accessing the number. For
that you need an external object of some sort (or shared activation
groups which are not available to application code).
You could force a single sequence by submitting the invoice generation
job to a single-threaded job queue, or you could have a never-ending
batch program that accepts requests to generate invoices from a data
queue or socket connexion but these are flawed approaches.
Or, maybe I'm asking the wrong question. How can I make sure to
programs that run simultaneously can be guaranteed a unique sequential
number?
Decide on an appropriate external object to contain the next number.
This is either the next number to use or the last number used
depending on how you increment it. This object can be a data area,
file, user space, or anything else suitable. Your application, at the
start of each invoice creation, would lock the 'next number' object in
some way (e.g., ALCOBJ, LOCK, etc. for a data area, normal record
locking for a file, perhaps CMPSWP for a user space), then either:
1) read the current value which becomes your 'next' number, increment
and write the new 'next' number back to the object.
2) read the current value which is the 'last used' value, increment
it to get the new number and write back to the object.
Release the locks--for a file this will happen automatically as a
result of updating the record.
Thus you have a robust and reliable method for assigning 'next'
numbers that will work across jobs. The only issue is if a user
decides to cancel an invoice then there will be gaps in the sequence.
That can be handled by:
1) an audit log that tracks information about cancelled documents.
or
2) don't get the invoice number until the user has committed to
creating the invoice (i.e., do the processing described above at the
end of the invoice cycle instead of the start).
Regards,
Simon Coulter.
--------------------------------------------------------------------
FlyByNight Software OS/400, i5/OS Technical Specialists
http://www.flybynight.com.au/
Phone: +61 2 6657 8251 Mobile: +61 0411 091 400 /"\
Fax: +61 2 6657 8251 \ /
X
ASCII Ribbon campaign against HTML E-Mail / \
--------------------------------------------------------------------
As an Amazon Associate we earn from qualifying purchases.