2016-05-03 47 views
0

快速故事背景:休眠:力「與(NOLOCK)」的所有選擇查詢提示,在不改變隔離級別

我在最近已經具有與該數據庫的鎖定問題,一個很老的應用程序。該應用程序是用Java編寫的,並使用Hibernate。我們發現的其中一個問題是長時間不活躍的事務,而且隔離級別經常在READ_COMMITED和READ_UNCOMMITED之間變化。雖然我們承認明確的解決方案是重構代碼,以便交易規模較小,但這將是我們目前無法完全承擔的巨大努力(應用程序的大多數已用部分正在遷移到新系統,但此過程相對較慢)。

因此 - 因爲我們對所有的Select操作使用READ_UNCOMMITED,而對其他所有操作使用READ_COMMITED,所以一直在幫助我們的DBA確定了將隔離級別更改爲全局READ_COMMITED的可能解決方案,並將所有選擇查詢更改爲包含提示'(NOLOCK)'。他說,在功能上,檢索數據的方式應該沒有區別(因爲我們現在使用髒讀取而沒有問題),同時爲我們提供了無需頻繁更改事務內隔離級別的優勢。我相信他的想法也是關於最近有關數據庫鎖定是由隔離級別更改引起的報告。我們可以(如果是這樣,怎麼做?)告訴hibernate在通過使用映射的java對象和HQL自動生成的所有查詢中添加'with(nolock)'提示(甚至可能存在的SQL存在傳遞給休眠,雖然這似乎推動它:))沒有改變隔離級別?最後一點:我們使用的是舊版本的hibernate v3.5,現在升級的可能性不大,一些令人難以置信的「聰明」的人決定在某些時候玷污它,插入一些他們自己的代碼,應用使用。升級已經嘗試失敗多次。

另外:我檢查了很多相關的線程,一般的想法似乎是:不要使用nolock,改變隔離級別,如上所述 - 我們不打算這樣做。

編輯1:由於該應用程序在過去的12年中一直在不斷開發,因此當前開發團隊甚至沒有查看過一些模塊,理想的解決方案將不需要識別使用持久對象的每一個Java代碼位。

Edit2:一個可能的方式去做這件事 - 如果Hibernate允許的話 - 可能會添加一種Interceptor接收格式化的SQL查詢,然後傳遞給db驅動程序。然後,我會照顧自己添加提示,使用某種形式的正則表達式。

非常感謝您提前。

回答

0

您不能在HQL中使用(NOLOCK)。但是,如果您決定更改查詢,則可以使用本機SQL。例如:

getCurrentSession().createSQLQuery("select * from table with(NOLOCK)").list();