Para melhor visualização, recomendo resolução de no mínimo 1280 x 800 e navegador Mozilla Firefox


sexta-feira, 2 de outubro de 2015

Abordando o novo privilégio READ do Oracle 12c

Por Eduardo Legatti

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:

Postagens populares