一点背景:
我正在Django中编写一个函数来获取下一个发票号,它需要是连续的(而不是间隙),因此该函数如下所示:
def get_next_invoice_number():
"""
Returns the max(invoice_number) + 1 from the payment records
Does NOT pre-allocate number
"""
# TODO ensure this is thread safe
max_num = Payment.objects.aggregate(Max('invoice_number'))['invoice_number__max']
if max_num is not None:
return max_num + 1
return PaymentConfig.min_invoice_number
现在的问题是,这个函数只返回max()+1
,在我的生产环境中,我有多个Django进程,因此如果对两个不同的付款(在保存第一条记录之前)调用这个函数两次,它们将得到相同的发票号。你知道吗
为了缓解这个问题,我可以重写save()
函数来调用get_next_invoice_number()
,以最小化这些函数调用之间的时间间隔,但是问题发生的可能性仍然很小。你知道吗
所以我想在approve方法中实现一个锁,比如
from multiprocessing import Lock
lock = Lock()
class Payment(models.Model):
def approve(self):
lock.acquire()
try:
self.invoice_number = get_next_invoice_number()
self.save()
except:
pass
finally:
lock.release()
所以我的问题是:
更新:
到目前为止,最简单的方法是使用数据库中现有的用于创建序列的工具。实际上,如果您不介意从} 。你知道吗
1
开始的值,您可以使用Django的^{如果您的业务需求是这样的,您需要选择一个起始编号,那么您必须在数据库中了解如何执行此操作。这里有somequestions可能会有所帮助。你知道吗
尝试用锁或事务来确保这一点将更难做到,执行起来也更慢。你知道吗
相关问题 更多 >
编程相关推荐