2012-12-12 62 views
4

我的應用程序正在4個節點的羣集上運行。在啓動時(ServletContextListener),它必須執行一個SQL腳本。如何確保SQL只執行一次而不是4次,因爲每個節點都會嘗試執行相同的代碼?多節點環境(集羣),如何確保一個動作在啓動時只執行一次?

+0

ServletContextListener方法,contextInitialized方法將只在調用應用程序時調用一次。所以查詢只會觸發一次 –

+1

除羣集中有4個節點外,每個節點都運行它自己的應用程序副本,所以會有4個ServletContextListeners執行它們的contextInitialized方法。 –

+1

讓我問你,第一次到什麼時候,如果在停止1個節點並重新啓動之後會發生什麼,這是否算作新的啓動? –

回答

1

如果您只想執行一次(就像更新數據庫結構的腳本一樣),您應該在數據庫中使用某種版本字段(最簡單的情況就是單列/單行表)。如果你不想自己做,http://flywaydb.org/可能是你的解決方案。如果你只是想確保沒有實例同時運行相同的腳本,你基本上使用相同的想法,而不是使用增加的版本字段,而是使用相同類型的布爾鎖,在你的腳本完成之後你重置它。如果你想自己實現ist,一定要正確處理併發訪問。例如,而不是select entry from lock /if entry = 0 update lock set entry = 1這是非原子做類似update lock set entry = 1 where entry = 0/check if number affected rows = 1

+0

所以無論誰看到這個鎖是0將它設置爲1並運行sql腳本,並且每個不是第一個的人都會看到1,所以不會做任何事情?鎖何時將重置爲0? –

+0

是的,只需在腳本完成後重置即可。 – Drunix

+0

如果腳本在一秒鐘內完成,但節點的延遲開始時間比那更長,該怎麼辦?首先啓動節點將值設置爲1,啓動腳本,腳本結束,值復位爲0.第二個節點啓動,看到值爲0並重新啓動進程? –

相關問題