oracle执行比较大的存储过程中,同一个表,同一组数据,执行完UPDATE语句操作,并commit以后,紧接着执行MERGE INTO 语句时,会出现上面的UPDATE语句锁表的问题:
UPDATE PB_BALANCE_ACCOUNT_DTL T SET T.ENDCOST = NVL(T.BEGINCOST,0)+NVL(T.CURRENTCOST,0)
WHERE T.CORPORATION=corp AND T.FARM=fa AND T.MONTH=mon AND T.COSTSTATUS=0;
COMMIT;
-----
MERGE INTO PB_BALANCE_ACCOUNT_DTL T1
USING(
SELECT T.PID,T.COSTTYPE,T.ENDCOST ECOST,T.PPH FROM PB_BALANCE_ACCOUNT_DTL T WHERE T.COSTSTATUS=0 AND T.CORPORATION=corp AND T.FARM=fa AND T.MONTH=mon
)T2 ON(T1.PID=T2.PID AND T1.COSTTYPE=T2.COSTTYPE AND T1.CORPORATION=corp AND T1.FARM=fa AND T1.MONTH=mon AND T1.PPH=T2.PPH+1)
WHEN MATCHED THEN
UPDATE SET T1.BEGINCOST=T2.ECOST;
COMMIT;
上面两句语句,执行的是同一个表数据,第一句执行完update以后并commit;然后执行第二句merge into时,会锁定第一句update语句,造成表PB_BALANCE_ACCOUNT_DTL锁表;请oracle大神能江湖救急。
分析问题,第二句和第一句相互独立,提交后执行第二句,出问题也就只是第二句更新问题。为什么会锁定第一句的更新?
第二句锁表问题,没有看出merge into问题所在,建议探查一下数据是否存在更新T1时同时有T2条件的数据。
分析需求,根据语句看来没有插入命令,仅是自连接更新表内数据,插入更新改写成了更新语句(未验证)可以试试
update PB_BALANCE_ACCOUNT_DTL T1
set T1.BEGINCOST =
(select ECOST from PB_BALANCE_ACCOUNT_DTL t2
where T1.PID=T2.PID
AND T1.COSTTYPE=T2.COSTTYPE
AND T1.PPH=T2.PPH+1
AND T2.COSTSTATUS=0
AND T2.CORPORATION=corp
AND T2.FARM=fa
AND T2.MONTH=mon)
where T1.CORPORATION=corp
AND T1.FARM=fa
AND T1.MONTH=mon;
还是探查一下数据吧,如果要下着急解决这个问题,变通一下,可尝试分表记录,避免自关联更新
还是探查一下数据吧,如果眼下着急解决这个问题,变通一下,可尝试分表记录,避免自关联更新
自关联更新这样的表设计对人对系统都不友好,能避免最好在数据库设计阶段就避免