feat: handover_submit 并发优化

This commit is contained in:
caoqianming 2026-01-09 16:54:24 +08:00
parent 3417515e72
commit 6eee0e1e53
1 changed files with 31 additions and 40 deletions

View File

@ -22,7 +22,7 @@ from ..qm.models import Defect, Ftest
from django.db.models import Count, Q from django.db.models import Count, Q
from apps.utils.tasks import ctask_run from apps.utils.tasks import ctask_run
from apps.mtm.models import Process from apps.mtm.models import Process
from apps.utils.lock import lock_model_record_d_func from django.db.models import F
myLogger = logging.getLogger('log') myLogger = logging.getLogger('log')
@ -696,11 +696,15 @@ def update_mtask(mtask: Mtask, fill_way: int = 10):
# utask.state = Utask.UTASK_SUBMIT # utask.state = Utask.UTASK_SUBMIT
utask.save() utask.save()
@lock_model_record_d_func(Handover)
def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime, None]): def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime, None]):
""" """
交接提交后需要执行的操作 交接提交后需要执行的操作
""" """
handover = (
Handover.objects
.select_for_update()
.get(pk=handover.pk)
)
if handover.submit_time is not None: if handover.submit_time is not None:
return return
now = timezone.now() now = timezone.now()
@ -744,7 +748,11 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
wmId, xcount, handover_or_b = item wmId, xcount, handover_or_b = item
if xcount <= 0: if xcount <= 0:
raise ParseError("存在非正数!") raise ParseError("存在非正数!")
wm_from = WMaterial.objects.get(id=wmId) wm_from = (
WMaterial.objects
.select_for_update()
.get(id=wmId)
)
mids.append(wm_from.material.id) mids.append(wm_from.material.id)
# 合并为新批 # 合并为新批
@ -768,25 +776,24 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
batch = wm_from.batch batch = wm_from.batch
batches.append(batch) batches.append(batch)
if wm_from is None: updated = (
raise ParseError(f'{wm_from.batch} 找不到车间库存') WMaterial.objects
.filter(id=wm_from.id, count__gte=xcount)
count_x = wm_from.count - xcount .update(count=F('count') - xcount)
if count_x < 0: )
if updated == 0:
raise ParseError(f'{wm_from.batch} 车间库存不足!') raise ParseError(f'{wm_from.batch} 车间库存不足!')
else:
wm_from.count = count_x
wm_from.save()
if need_add: if need_add:
# 开始变动 # 开始变动
if handover.type == Handover.H_NORMAL: if handover.type == Handover.H_NORMAL:
if mtype == Handover.H_MERGE and handover.new_wm: if mtype == Handover.H_MERGE and handover.new_wm:
wm_to = handover.new_wm wm_to = WMaterial.objects.select_for_update().get(id=handover.new_wm.id)
if wm_to.state != wm_from.state or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect: if wm_to.state != wm_from.state or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect:
raise ParseError("正常合并到的车间库存状态或物料异常") raise ParseError("正常合并到的车间库存状态或物料异常")
else: else:
wm_to, _ = WMaterial.objects.get_or_create( wm_to, _ = WMaterial.locked_get_or_create(
batch=batch, batch=batch,
material=material, material=material,
mgroup=recive_mgroup, mgroup=recive_mgroup,
@ -806,11 +813,11 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
recive_mgroup = handover.recive_mgroup recive_mgroup = handover.recive_mgroup
wm_state = WMaterial.WM_REPAIR wm_state = WMaterial.WM_REPAIR
if mtype == Handover.H_MERGE and handover.new_wm: if mtype == Handover.H_MERGE and handover.new_wm:
wm_to = handover.new_wm wm_to = WMaterial.objects.select_for_update().get(id=handover.new_wm.id)
if wm_to.state != WMaterial.WM_REPAIR or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect: if wm_to.state != WMaterial.WM_REPAIR or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect:
raise ParseError("返修合并到的车间库存状态或物料异常") raise ParseError("返修合并到的车间库存状态或物料异常")
elif recive_mgroup: elif recive_mgroup:
wm_to, _ = WMaterial.objects.get_or_create( wm_to, _ = WMaterial.locked_get_or_create(
batch=batch, batch=batch,
material=material, material=material,
mgroup=recive_mgroup, mgroup=recive_mgroup,
@ -828,28 +835,13 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
) )
else: else:
raise ParseError("返工交接必须指定接收工段") raise ParseError("返工交接必须指定接收工段")
elif handover.type == Handover.H_TEST:
raise ParseError("检验交接已废弃")
wm_to, _ = WMaterial.objects.get_or_create(
batch=batch,
material=material,
mgroup=recive_mgroup,
state=WMaterial.WM_TEST,
belong_dept=recive_dept,
defaults={
"count_xtest": 0,
"batch_ofrom": wm_from.batch_ofrom,
"material_ofrom": wm_from.material_ofrom,
"create_by": user
},
)
elif handover.type == Handover.H_SCRAP: elif handover.type == Handover.H_SCRAP:
if mtype == Handover.H_MERGE and handover.new_wm: if mtype == Handover.H_MERGE and handover.new_wm:
wm_to = handover.new_wm wm_to = WMaterial.objects.select_for_update().get(id=handover.new_wm.id)
if wm_to.state != WMaterial.WM_SCRAP or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect: if wm_to.state != WMaterial.WM_SCRAP or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect:
raise ParseError("报废合并到的车间库存状态或物料异常") raise ParseError("报废合并到的车间库存状态或物料异常")
elif recive_mgroup: elif recive_mgroup:
wm_to, _ = WMaterial.objects.get_or_create( wm_to, _ = WMaterial.locked_get_or_create(
batch=batch, batch=batch,
material=material, material=material,
mgroup=recive_mgroup, mgroup=recive_mgroup,
@ -868,11 +860,11 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
raise ParseError("不支持非工段报废") raise ParseError("不支持非工段报废")
elif handover.type == Handover.H_CHANGE: elif handover.type == Handover.H_CHANGE:
if mtype == Handover.H_MERGE and handover.new_wm: if mtype == Handover.H_MERGE and handover.new_wm:
wm_to = handover.new_wm wm_to = WMaterial.objects.select_for_update().get(id=handover.new_wm.id)
if wm_to.material != handover.material_changed or wm_to.state != handover.state_changed: if wm_to.material != handover.material_changed or wm_to.state != handover.state_changed:
raise ParseError("改版合并到的车间库存状态或物料异常") raise ParseError("改版合并到的车间库存状态或物料异常")
elif handover.recive_mgroup: elif handover.recive_mgroup:
wm_to, _ = WMaterial.objects.get_or_create( wm_to, _ = WMaterial.locked_get_or_create(
batch=batch, batch=batch,
material=handover.material_changed, material=handover.material_changed,
state=handover.state_changed, state=handover.state_changed,
@ -895,9 +887,9 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
if wm_from and wm_from.state != WMaterial.WM_OK: if wm_from and wm_from.state != WMaterial.WM_OK:
raise ParseError("仅合格品支持退回") raise ParseError("仅合格品支持退回")
if mtype == Handover.H_MERGE and handover.new_wm: if mtype == Handover.H_MERGE and handover.new_wm:
wm_to = handover.new_wm wm_to = WMaterial.objects.select_for_update().get(id=handover.new_wm.id)
else: else:
wm_to, _ = WMaterial.objects.get_or_create( wm_to, _ = WMaterial.locked_get_or_create(
batch=batch, batch=batch,
material=material, material=material,
mgroup=recive_mgroup, mgroup=recive_mgroup,
@ -915,9 +907,9 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
else: else:
raise ParseError("不支持该交接类型") raise ParseError("不支持该交接类型")
wm_to.count = wm_to.count + xcount WMaterial.objects.filter(id=wm_to.id).update(count=F('count') + xcount)
wm_to.count_eweight = handover.count_eweight # 这行代码有隐患 if handover.count_eweight:
wm_to.save() WMaterial.objects.filter(id=wm_to.id).update(count_eweight=handover.count_eweight)
handover_or_b.wm_to = wm_to handover_or_b.wm_to = wm_to
handover_or_b.save() handover_or_b.save()
if material.tracking == Material.MA_TRACKING_SINGLE: if material.tracking == Material.MA_TRACKING_SINGLE:
@ -943,7 +935,6 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime,
ana_batch_thread(xbatchs=batches) ana_batch_thread(xbatchs=batches)
@lock_model_record_d_func(Handover)
def handover_revert(handover:Handover, handler:User=None): def handover_revert(handover:Handover, handler:User=None):
if handover.submit_time is None: if handover.submit_time is None:
raise ParseError('该交接单未提交!') raise ParseError('该交接单未提交!')