記一次oracle sql語句未提交引起的生產問題

問題:今天幫助同事排查生產問題,遇到一個oracle執行語句未提交引起的坑。以下記錄警醒自己。

現象:頁面上某一個按鈕點擊之後,總會有不確定性的延遲--並不是正常延遲。

排查:查看日誌,發現總是執行到一個服務中,執行失敗。這個服務中有三條sql語句,前兩條是更新update,第三條是刪除delete。這幾個操作總是發生不定性的錯誤,執行延遲等問題。

分析:oracle中DML語句執行需要提交commit,如果不提交的話,執行同一個表會發生鎖表或鎖行。這就會導致某條sql語句執行巨慢的現象--並不是數據量大的問題。公司框架提供了兩種執行數據庫操作語句的方法,一個是不斷開連接的,一種是斷開連接並進行提交的,正常情況下執行DML語句的話,使用斷開連接的;執行查詢語句的話,一般使用不斷開連接的,因爲後面會打開遊標取查詢結果數據。這個生產問題,便是用錯了這兩種執行sql的方法造成的。

總結:

使用公司封裝的架構方法,爲了兼容各種情況,一般會提供各種場景使用到的方法,使用者使用的時候要看清楚每一層,框架提供了哪些方法,有什麼不同,不要盲目的生搬硬套,選擇適合當下業務場景的方法。

oracle數據庫有表鎖、行鎖兩種鎖。

行鎖:一般是排他鎖,被鎖定的行不能被更改、刪除,只能被select,但是加排他鎖之前一般會先加表級鎖,。

表鎖:一般是共享鎖,是不可以對該表執行DDL語句的,但DML操作都不限制,行級鎖之前需要先加表結構共享鎖。

併發:對於高併發​更新的數據庫表使用行級鎖,避免使用表級鎖,頁級鎖(mysql);

數據庫操作語句的分類:

  • DDL:數據庫模式定義語言,關鍵字:create
  • DML:數據操縱語言,關鍵字:Insert、delete、update
  • DCL:數據庫控制語言 ,關鍵字:grant、remove
  • DQL:數據庫查詢語言,關鍵字:select

鎖表及解鎖:

1、查看哪些表被鎖定了:sqlplus / as sysdba;

select t2.username,
       t2.sid,
       t2.serial#,
       t3.object_name,
       t2.OSUSER,
       t2.MACHINE,
       t2.PROGRAM,
       t2.LOGON_TIME,
       t2.COMMAND,
       t2.LOCKWAIT,
       t2.SADDR,
       t2.PADDR,
       t2.TADDR,
       t2.SQL_ADDRESS,
       t1.LOCKED_MODE
  from v$locked_object t1, v$session t2, dba_objects t3
 where t1.session_id = t2.sid
   and t1.object_id = t3.object_id
 order by t2.logon_time;

2、解除鎖定

alter system kill session 'sid,seial#';

此外:oracle提供了三種語句提交方式

1、顯式提交:用COMMIT命令直接完成的提交爲顯式提交。其格式爲:SQL>COMMIT;或者代碼語句中最後commit。
2、隱式提交: 用SQL命令間接完成的提交爲隱式提交。這些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
3、自動提交:若把AUTOCOMMIT設置爲ON,則在插入、修改、刪除語句執行後,系統將自動進行提交,這就是自動提交。其格式爲:SQL>SET AUTOCOMMIT ON;

如何查看oracle數據庫是否開啓自動提交服務:

sqlplus / as sysdbs;

show auto;

OFF-未開啓;ON-開啓。

設置自動提交:

set autocommit on;

在數據庫的插入、刪除和修改操作時,只有當事務在提交到數據庫時纔算完成,在Oracle數據庫中,在事務提交前,只有操作數據庫的這個人纔能有權看到所做的事情,別人只有在最後提交完成後纔可以看到。因爲Oracle數據庫的默認事務隔離級別是提交讀(Read Committed)。

提交數據有三種類型:顯式提交、隱式提交及自動提交

需要注意的是,無論AUTOCOMMIT設置爲何值,當退出SQL*Plus時,當前會話所有的DML操作所改變的數據都會被提交。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章