Olá,
Para que um usuário no Oracle acesse objetos de um outro usuário, é necessário conceder privilégios de banco de dados para este usuário. Os privilégios mais comuns que utilizamos são os privilégios de objeto DML (SELECT, INSERT, DELETE, UPDATE). Quando queremos que um usuário tenha acesso apenas de leitura nas tabela de um outro usuário geralmente concedemos apenas o privilégio SELECT. Neste caso, temos a opção de conceder o privilégio de sistema SELECT ANY TABLE, ou conceder o privilégio de objeto SELECT para cada tabela do usuário. O problema com o privilégio SELECT, é que apesar de não haver qualquer risco de que dados sejam alterados com ele, o mesmo oferece a possibilidade de gerar bloqueios (locks) quando fazemos SELECT utilizando a cláusula FOR UPDATE. Por isso, o usuário que até então deveria ter acesso somente leitura, se mal intencionado pode causar sérios problemas de bloqueios no banco de dados. Para resolver este problema, o Oracle 12c (12.1.0.2.0) veio com um novo privilégio chamado READ que impede a geração de locks no banco de dados quando fazemos uso da cláusula FOR UPDATE em uma instrução SELECT. Veja abaixo uma demonstração.
C:\>sqlplus / as sysdba
SQL*Plus: Release 12.1.0.2.0 Production on Sex Out 2 10:09:52 2015
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Conectado a:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> create user scott identified by tiger;
Usuário criado.
SQL> grant create session, select any table, select any dictionay to scott;
Concessão bem-sucedida.
SQL> connect scott/tiger
Conectado.
SQL> select * from ADAM.T1 FOR UPDATE;
ID
----------
1
2
3
4
5
6
7
8
9
10
10 linhas selecionadas.
Após a criação do usuário SCOTT e a concessão do privilégio SELECT ANY TABLE para ele, efetuei o SELECT FOR UPDATE na tabela T1 de propriedade do usuário ADAM. Consultando a view dinâmica de desempenho V$LOCK, é possível notar um ROW EXCLUSIVE LOCK na tabela T1 conforme demonstrado abaixo.
SQL> select
2 o.object_name,
3 o.object_type,
4 s.sid,
5 s.serial#,
6 s.username,
7 s.type,
8 Decode( l.lmode,
9 0, 'None',
10 1, 'Null',
11 2, 'Row Share',
12 3, 'Row Exclu',
13 4, 'Share',
14 5, 'Sh Row Ex',
15 6, 'Exclusive',
16 'Null' ) "lock_mode"
17 from dba_objects o,
18 v$lock l,
19 v$session s
20 where l.id1 = + O.object_id
21 and s.sid = l.sid
22 and s.username is not null;
OBJECT_NAM OBJECT_TYPE SID SERIAL# USERNAME TYPE lock_mode
---------- -------------- ---------- ---------- ------------------ ---------- ---------
T1 TABLE 34 18457 SCOTT USER Row Exclu
ORA$BASE EDITION 254 2207 SYS USER Share
ORA$BASE EDITION 253 6089 SYS USER Share
ORA$BASE EDITION 34 18457 SCOTT USER Share
No caso acima, se o usuário ADAM ou qualquer outro usuário que tenha privilégios tentar realizar alguma instrução DML na tabela T1 ficará bloqueado, ou seja, o mesmo ficará aguardando que a sessão do usuário SCOTT seja finalizada (COMMIT ou ROLLBACK). Para resolver esse problema e fazer com que o usuário SCOTT se torne realmente um usuário READ ONLY, bastará revogarmos o privilégio SELECT ANY TABLE e conceder o privilégio READ ANY TABLE, conforme a seguir.
SQL> connect / as sysdba
Conectado.
SQL> revoke select any table from scott;
Revogação bem-sucedida.
SQL> grant read any table to scott;
Concessão bem-sucedida.
SQL> connect scott/tiger
Conectado.
Pronto. Agora o usuário SCOTT poderá somente ler as as tabelas sem impor qualquer tipo de bloqueio nas mesmas. Vale a pena salientar que também é possível conceder o privilégio READ no nível de objeto.
SQL> select * from ADAM.T1 FOR UPDATE;
select * from ADAM.T1 FOR UPDATE
*
ERRO na linha 1:
ORA-01031: privilégios insuficientes
SQL> select * from ADAM.T1;
ID
----------
1
2
3
4
5
6
7
8
9
10
10 linhas selecionadas.
Nenhum comentário:
Postar um comentário