1. 程式人生 > 其它 >資料庫出現死鎖怎麼辦?

資料庫出現死鎖怎麼辦?

前言

最近接到一個需求,需要同步二十萬條資料到我們資料庫來,然而過程並不太順利,解決之後來總結一下。

問題

同步的時候會報錯,導致同步失敗出現死鎖問題。
在這裡插入圖片描述
出現死鎖沒許可權,又不得不麻煩同事幫忙解開,關於解鎖直接百度即可http://blog.itpub.net/26812308/viewspace-2120485/

優化

後來瞭解情況後發現程式碼中沒有事務的相關處理,涉及到資料量很大如果出現網路波動或其他訪問操作同一張表就會容易引發死鎖問題。

PROCEDURE sync_mnt_five_tree IS
    struction_2_t_num  NUMBER;
    struction_3_t_num  NUMBER;
struction_4_t_num NUMBER; struction_5_t_num NUMBER; mm_contract_no_num NUMBER; orgs_info_t_num NUMBER; elevators_t_num NUMBER; update_num NUMBER; CURSOR v_cur IS SELECT * FROM [email protected] where ORG_ID is not null and AREA_ID is not null;
BEGIN update_num :=0; FOR v_row IN v_cur LOOP update_num := update_num+1; --二級 SELECT COUNT(1) INTO struction_2_t_num FROM struction_2_t t WHERE t.struction_2_id = to_char(v_row.mnt_contract_id); IF struction_2_t_num > 0 THEN UPDATE struction_2_t t SET t.
struction_2_name = v_row.customer_name, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.struction_2_id = to_char(v_row.mnt_contract_id); ELSE INSERT INTO struction_2_t (struction_2_id, struction_2_code, struction_2_name, object_version, created_by, created_time, updated_by, updated_time) VALUES (to_char(v_row.mnt_contract_id), NULL, v_row.customer_name, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; --三級 SELECT COUNT(1) INTO struction_3_t_num FROM struction_3_t t WHERE t.struction_3_id = to_char(v_row.area_id); IF struction_3_t_num > 0 THEN UPDATE struction_3_t t SET t.struction_3_name = v_row.area, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.struction_3_id = to_char(v_row.area_id); ELSE INSERT INTO struction_3_t (struction_3_id, struction_3_code, struction_3_name, object_version, created_by, created_time, updated_by, updated_time) VALUES (to_char(v_row.area_id), NULL, v_row.area, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; --四級 SELECT COUNT(1) INTO struction_4_t_num FROM struction_4_t t WHERE t.struction_4_id = to_char(v_row.project_id); IF struction_4_t_num > 0 THEN UPDATE struction_4_t t SET t.struction_4_name = v_row.project_name, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.struction_4_id = to_char(v_row.project_id); ELSE INSERT INTO struction_4_t (struction_4_id, struction_4_code, struction_4_name, object_version, created_by, created_time, updated_by, updated_time) VALUES (to_char(v_row.project_id), NULL, v_row.project_name, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; --五級 SELECT COUNT(1) INTO struction_5_t_num FROM struction_5_t t WHERE t.struction_5_id = to_char(v_row.building_id); IF struction_5_t_num > 0 THEN UPDATE struction_5_t t SET t.struction_5_name = v_row.building_name, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.struction_5_id = to_char(v_row.building_id); ELSE INSERT INTO struction_5_t (struction_5_id, struction_5_code, struction_5_name, object_version, created_by, created_time, updated_by, updated_time) VALUES (to_char(v_row.building_id), NULL, v_row.building_name, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; ------ SELECT COUNT(1) INTO mm_contract_no_num FROM maintenance_message_t t WHERE t.mm_contract_no = v_row.mnt_contract_no; IF mm_contract_no_num > 0 THEN UPDATE maintenance_message_t t SET t.mm_start_time = v_row.begin_date, t.mm_end_time = v_row.end_date, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.mm_contract_no = v_row.mnt_contract_no; ELSE INSERT INTO maintenance_message_t (mm_id, mm_contract_no, mm_start_time, mm_end_time, object_version, created_by, created_time, updated_by, updated_time) VALUES (to_char(v_row.mnt_contract_id), v_row.mnt_contract_no, v_row.begin_date, v_row.end_date, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; --------- SELECT COUNT(1) INTO orgs_info_t_num FROM orgs_info_t t WHERE t.org_id = to_char(v_row.org_id); IF orgs_info_t_num > 0 THEN UPDATE orgs_info_t t SET t.org_id = to_char(v_row.org_id), t.org_syn_id = to_char(v_row.org_id), -- t.org_name = v_row. t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.org_id = to_char(v_row.org_id); ELSE INSERT INTO orgs_info_t (org_id, org_name, org_syn_id, object_version, created_by, updated_time, created_time, updated_by) VALUES (to_char(v_row.org_id), NULL, to_char(v_row.org_id), 1, 'system', SYSDATE, SYSDATE, 'system'); END IF; --------- SELECT COUNT(1) INTO elevators_t_num FROM elevators_t t WHERE t.ele_contract_no = v_row.ele_contract_no; IF elevators_t_num > 0 THEN UPDATE elevators_t t SET t.ele_contract_no = v_row.ele_contract_no, t.updated_by = 'system', t.updated_time = SYSDATE WHERE t.ele_contract_no = v_row.ele_contract_no; ELSE INSERT INTO elevators_t (ele_contract_no, object_version, created_by, created_time, updated_by, updated_time) VALUES (v_row.ele_contract_no, 1, 'system', SYSDATE, 'system', SYSDATE); END IF; -----------每一千條提交一次 IF update_num > 1000 THEN update_num :=0; COMMIT; END IF; END LOOP; COMMIT; END;

總結

簡單做個計數器,每次迴圈進行加一,到達一千條資料commit一次,這樣能及時提交,減少衝突問題。