我在我們的java項目中遇到了一個奇怪的HSQLDB行爲。非常簡單的查詢返回不一致的結果。我將問題追溯到某些表格的索引中,這些表格並不是最新的。不幸的是,我在SQL和數據庫處理方面都不是專家。HSQLDB索引不一致
HSQLDB版本是2.2.8。我試圖更新到2.2.9,但沒有幫助。
我們的數據庫非常簡單。它包含幾個獨立的表格。他們之間沒有關係。每張桌子都配備了索引,其中一個索引組合了幾列。這裏是一個例子:
CREATE CACHED TABLE PUBLIC.MYTABLE(
A BIGINT DEFAULT -9999 NOT NULL,
B BIGINT DEFAULT -9999 NOT NULL,
C NUMERIC(12,7) DEFAULT -9999.0000000 NOT NULL,
D INTEGER DEFAULT -9999 NOT NULL);
CREATE INDEX IDX1 ON PUBLIC.MYTABLE(A);
CREATE INDEX IDX2 ON PUBLIC.MYTABLE(B);
CREATE INDEX IDX3 ON PUBLIC.MYTABLE(C);
CREATE UNIQUE INDEX MYTABLE_PRIMARY_KEY ON PUBLIC.MYTABLE(A, B);
我們通常從java程序中插入行和查詢表,從不更新現有的行。插入操作看起來是這樣的:
Connection con = ...; // get connection from
PreparedStatement stmt;
con.setAutoCommit(false);
stmt = this.con.prepareStatement(
String.format(
"insert into %s values (?,?,?,?)", "MYTABLE"));
stmt.setLong(1, data1);
stmt.setLong(2, data2);
stmt.setDouble(3, data3);
stmt.setInt(4, data4);
stmt.addBatch()
和其他地方,我們執行批處理
stmt.executeBatch();
stmt.clearBatch();
con.commit();
的代碼在循環中執行,在這之後我們關閉語句,用適當的方法連接。此外,連接URL在最後有「shutdown = true」,所以我們期望數據庫能夠正確關閉。
正如我前面提到的,我注意到這個問題時,SQL查詢等
SELECT COUNT(*) FROM MYTABLE
開始返回不合理的結果,比如它返回只有大約一半的行的預期數量。作爲一個實驗,我從表中刪除了唯一索引,並且所有查詢都正常工作。這就是爲什麼我認爲由於某種原因索引沒有正確更新插入。尋找索引的線索來自於谷歌搜索和閱讀留言板和論壇上的評論。
如Disable and rebuild an index in HSQLDB描述我用
SHUTDOWN COMPACT
和醫治我們的數據庫中所有表,所有的數據是存在的,所有的查詢返回正確的結果。我懷疑這個問題的作者有類似於我的問題。
好吧,我的數據是安全的,所以我想了解和糾正問題的根源。
索引是否應該在插入時更新?或者這是一個錯誤的假設,我們每次更新數據庫時都需要執行SHUTDOWN COMPACT?
是否有可能多個列上的唯一索引是問題的根源?
我希望有任何建議或指示。
謝謝你的建議。我將嘗試在虛擬數據上重現此問題。 – stys
試圖用虛擬數據重現問題,但失敗。一切工作正常。還檢查了幾個部署的數據庫,他們都很好。該問題僅出現在我用於在計算機上測試的兩個數據庫中。我認爲在我調試應用程序時可能會出現一些違反索引的特殊情況。 – stys
我仍在試圖找出問題的根源。有一件事是,使用「停止」按鈕終止NetBeans IDE中的進程存在問題。這裏詳細描述[Bug 22641](http://netbeans.org/bugzilla/show_bug.cgi?id=22641)。簡而言之,使用停止按鈕不會調用關閉鉤子,並且我的數據庫關閉代碼恰好在那裏。我經常使用那個按鈕,所以在數據庫沒有適當關閉時可能會有很多次。 – stys