2014-01-24 47 views
1

開始交易在高層次上,我有什麼是這樣的:MySQL的 - 鎖定表或觸發

所填充,並通過應用程序1.
  • A「從管理
    1. 「主」數據庫'數據庫使用standard mechanism從「主」數據庫複製的單獨主機上。
    2. 應用程序2獨立於應用程序1運行,對從屬數據庫具有非常有限的只讀訪問權和對其自己的獨立數據庫的讀寫訪問權限。

    ,基本上需要採取什麼措施是,當某些事情在「從」數據庫應用改變2只需要得到通知,以便它可以檢查「從」數據庫的內容,寫了一些東西變成自己的數據庫。

    性能不是問題,在發生這種情況時鎖定整個「從屬」數據庫是可以接受的。 關鍵的是要確保在應用程序2完成其任務之前,沒有更多信息被複制到「從屬」數據庫中。應用程序2從一個獨立於觸發通知的會話訪問「從」數據庫。

    要做到這一點,我有以下觸發

    delimiter // 
    CREATE TRIGGER create_report_trigger AFTER UPDATE ON jobs 
         FOR EACH ROW 
           BEGIN 
             DECLARE report_id INT; 
             IF (NEW.status = 7 AND OLD.status != 7) THEN 
               CALL CREATE_REPORT_PROC(NEW.id, @report_id); 
             END IF; 
           END; 
         // 
    delimiter ; 
    

    ...因爲你不能開始交易或從一個觸發器中鎖定數據庫,我也有以下程序

    delimiter // 
    CREATE PROCEDURE create_report_proc( 
         IN jobId INT, 
         OUT report_id INT 
    ) 
         BEGIN 
           START TRANSACTION WITH CONSISTENT SNAPSHOT; 
           SELECT CREATE_REPORT(jobId) INTO report_id; 
           COMMIT; 
         END // 
    delimiter ; 
    

    的步驟呼喚它使用的libcurl聯繫申請2,讓它知道它需要一個user-defined function處理工作。

    當我在MySQL命令行上手動調用它時,該過程非常完美。然而,當它被從觸發器調用,出現在MySQL日誌以下錯誤:

    Explicit or implicit commit is not allowed in stored function or trigger

    ...所以顯然MySQL是足夠聰明來檢測,我已經試圖顛覆其「無鎖定從觸發器內部「規則中,通過將觸發器委託給過程。

    用戶定義的函數等待應用程序2的操作完成,然後將結果返回給其調用者,這可能是相關的(如果MySQL複製過程基本上被觸發器執行阻止,則不需要手動鎖定任何東西;複製過程是唯一能夠對「從」數據庫進行更改的東西)。

    無論如何,我想這裏有兩個問題:

    1. 由於觸發器觸發由MySQL的複製工藝製成的更新的結果,這是否意味着在複製過程被阻塞,直到觸發回報?

    2. 如果不是,我該如何鎖定數據庫或以其他方式停止觸發器的複製過程?我想從觸發器內發出一個STOP SLAVE;可以做到這一點?

    編輯 - 而這裏的獎金的後續問題:

    當應用2去儘自己的事情,它看到的數據沒有反映,應該是在「從」的最新信息數據庫。具體而言,作爲觸發事務的一部分對jobs表進行的任何更新對於應用程序2都是不可見的。

    爲什麼這是這種情況,因爲觸發器配置爲激發AFTER UPDATE?是否有任何方法可以使新內容對數據庫中的應用程序2可見,還是有必要手動收集並傳遞所有更新的字段值作爲發送通知的一部分?

  • 回答

    2

    好了,根據我自己的研究:

    1. 觸發器執行是同步的,直到觸發完成阻塞調用線程。默認情況下,MySQL複製本質上是一個單線程進程(我認爲即使啓用多線程複製,每個數據庫也只能獲得一個線程)。所以在我的情況下,爲了所有實際目的,阻止複製線程「鎖定」數據庫;除了具有寫入權限的複製線程外,沒有其他人。

    2. 您不明確。然而,觸發器的執行被認爲是觸發它的事務的一部分,這意味着無論如何你都可以被隱式地鎖定在原子事務中。發生這種情況的程度似乎取決於您的存儲引擎和事務隔離設置。

    3. 仍然不完全確定'獎金'的問題,但我猜測它與#2有關。如果觸發器的執行是觸發它的事務的一部分,那麼該事務在觸發器完成之後才能提交。如果事務沒有提交,那麼其他會話的觀察者將無法看到其中的任何更改。

      在任何情況下,將更新的字段作爲參數傳遞給UDF可以很好地解決此問題。