Frappe allows automatically naming documents. One of the autoname options is ‘Naming Series’ as follows -
When naming_series
option is used, a numerical sequence number is maintained in tabSeries
table against each series key. e.g SO-, SINV-, PO- etc.
Every time a new document is created, getseries
function in naming.py
is called to get the next sequence number to be used for the document. The function is as follows -
def getseries(key, digits, doctype=''):
# series created ?
current = frappe.db.sql("select `current` from `tabSeries` where name=%s for update", (key,))
if current and current[0][0] is not None:
current = current[0][0]
# yes, update it
frappe.db.sql("update tabSeries set current = current+1 where name=%s", (key,))
current = cint(current) + 1
else:
# no, create it
frappe.db.sql("insert into tabSeries (name, current) values (%s, 1)", (key,))
current = 1
return ('%0'+str(digits)+'d') % current
The above function locks a row in tabSeries
table for update and increments its value by 1. The row remains locked until the entire operation of saving the document is completed. This essentially means we cannot create multiple documents of same type concurrently.
What If, we do following -
At the server start, reserve lets say 100 sequence numbers and allocate the same from memory to new documents getting created. Reserve 100 more when we run out of sequences. We dont have to lock a row in tabSeries
for each document and can essentially create multiple documents concurrently.
e.g. consider current naming series values for Sales Order doctype
tabSeries
name current
SO- 123
At server startup we reserve 100 sequence numebrs and update the value as follows -
tabSeries
name current
SO- 223
and in the get_series
method, keep on returning the value from memory keeping track of last issued value.
We can handle error scenarios like server restart etc by resetting the value at startup based on the last document created of any type.
Any views?