限制訪問表的FOR UPDATE操作
幾年以前有朋友問過類似的問題,當時考慮了一下,沒有想到好的解決方法,前些天有客戶詢問同樣的問題,沒有辦法週末仔細琢磨了一下,總算是找到一個解決的方法。
其實現在Oracle有專門的工具可以解決這個問題,就是Oracle的FireWall,透過直連的配置方式可以阻塞預配置好的FOR UPDATE操作,不過那需要單獨的軟體。這裡主要方案是要透過資料庫現有的功能實現這個目標。
限制FOR UPDATE是有實際意義的,有時候只希望給使用者分配查詢許可權,但是一旦分配了SELECT許可權後,使用者就自動擁有了FOR UPDATE能力,雖然使用者並沒有真正UPDATE的許可權,但是仍然可以將表的記錄鎖定,而這有時候並不是所期望的。
SQL> conn test/test
Connected.
SQL> create table t_update (id number, name varchar2(30));
Table created.
SQL> insert into t_update values (1, 'a');
1 row created.
SQL> commit;
Commit complete.
SQL> create user u1 identified by u1;
User created.
SQL> grant create session to u1;
Grant succeeded.
SQL> grant select on t_update to u1;
Grant succeeded.
切換到U1使用者,現在可以對T_UPDATE進行SELECT FOR UPDATE操作:
SQL> conn u1/u1
Connected.
SQL> set sqlp 'SQL2> '
SQL2> select * from test.t_update where id = 1 for update;
ID NAME
---------- ------------------------------
1 a
為了避免FOR UPDATE操作,可以封裝一層檢視。
SQL> create view v_update as select * from t_update;
View created.
SQL> grant select on v_update to u1;
Grant succeeded.
但是如果僅是檢視,那麼沒有任何作用,FOR UPDATE操作同樣可以對單表查詢的檢視執行:
SQL2> select * from test.v_update where id = 1 for update;
ID NAME
---------- ------------------------------
1 a
如果新增ROWNUM等偽列,可以避免直接FOR UPDATE:
SQL> create or replace view v_update as select rownum rn, a.* from t_update a;
View created.
但是如果FOR UPDATE指定ROWNUM偽列外的真實列,還是可以繞開:
SQL2> select * from
test.v_update where id = 1 for update;
select * from test.v_update where id = 1 for update
*
ERROR at line 1:
ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
SQL2> select id, name from test.v_update where id = 1 for update;
ID NAME
---------- ------------------------------
1 a
透過報錯資訊可以看出,如果包含了GROUP BY或DISTINCT就可以阻止FOR UPDATE操作:
SQL> create or replace view v_update as select distinct * from t_update;
View created.
但是這種方式無疑會帶來效能問題,更重要的是,如果表中存在重複記錄,那麼DISTINCT操作會使得重複記錄丟失。
而最好的解決方法是採用UNION ALL方式建立檢視:
SQL> create or replace view
v_update as
2 select * from t_update
3 union all
4 select * from t_update where 1 = 2;
View created.
現在就達到了阻止FOR UPDATE的操作,且對於查詢基表的效能影響最小:
SQL2> select * from
test.v_update where id = 1 for update;
select * from test.v_update where id = 1 for update
*
ERROR at line 1:
ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.
對於不希望使用者執行FOR UPDATE操作的表,可以建立成UNION ALL檢視,並將檢視的查詢許可權授權給使用者。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-713128/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- .htaccess IP訪問限制
- iOS12訪問限制沒有了 ?iOS12訪問限制在哪iOS
- nginx限制ip訪問(轉)Nginx
- Windows限制訪問指定IPWindows
- go 突破訪問限制,訪問其他包中的私有變數Go變數
- Python 訪問限制 private publicPython
- 如何解決網站限制IP訪問的問題網站
- Oracle資料庫限制訪問IPOracle資料庫
- 限制特定IP訪問資料庫資料庫
- [zhuan]linux限制IP訪問sshLinux
- Oracle訪問表的方式Oracle
- 表連線時update與delete操作需注意的地方delete
- MySQL 常用的UPDATE操作MySql
- 如何限制ip訪問Oracle資料庫Oracle資料庫
- C++ 突破私有成員訪問限制C++
- Lumen 使用 throttle 限制介面訪問頻率
- 利用淘寶ip庫限制地區訪問
- nginx+lua(OpenResty),實現訪問限制NginxREST
- 【PRODUCE】Oracle 通過儲存過程限制使用者訪問表資料Oracle儲存過程
- 限制web專案下某目錄的直接訪問Web
- 求問介面訪問有時間限制的壓測怎麼做?
- 第 14 篇:限制介面的訪問頻率
- 資料庫限制/允許某些IP訪問資料庫
- Oracle 表訪問方式Oracle
- oracle表訪問方式Oracle
- MybatisPlus中的update操作MyBatis
- 【PRODUCE】Oracle 通過儲存過程限制使用者訪問表資料(二)Oracle儲存過程
- 如何在Linux中如何限制對su命令的訪問Linux
- Weblogic 提示5個IP訪問許可權的限制Web訪問許可權
- MongoDB更新(update)操作MongoDB
- UPDATE操作和UNDO
- 3.2.4 開啟資料庫到限制訪問模式資料庫模式
- 限制訪問Oracle客戶端IP方法總結Oracle客戶端
- Update操作對索引的影響索引
- 使用Bucket4j限制Spring API的訪問速率 - BaeldungSpringAPI
- MySQL限制IP網段範圍從遠端訪問的方法MySql
- 一、訪問物件屬性和方法的操作物件
- nginx對訪問路徑進行限制【部分介面可以內外網訪問、剩餘介面只可以內網訪問】Nginx內網