Cálculo sem Limite: A Teoria do Operador Autodestrutivo

A nova matemática, fruto dos trabalhos pioneiros de René Descartes (1596-1650) (a ideia do cogito ergo sum, que se materializou no plano cartesiano) e que atingiu um novo patamar com o método dos Fluxos de Isaac Newton (1643-1727) sofreu um duro golpe ainda em seus primeiros anos após a publicação dos trabalhos do bispo anglicano George Berkeley (1685-1753) no início do século XVIII. Independente de que vertente você goste mais (cálculo diferencial de Leibniz ou fluxos de Newton), o cálculo esbarra nos conceitos de limite, infinitésimo e continuidade desde o começo. Berkeley questionava a forma com que Newton obtinha suas derivadas. O problema era que o incremento “enxertado” no início do cálculo era descartado posteriormente por ser considerado desprezível. Se esse valor desprezível não fosse utilizado no começo, não daria certo, pois resultaria divisão por zero. Em sua crítica, Berkeley perguntava:

E o que são esses incrementos desvanecentes? Não são quantidades finitas nem infinitamente pequenas, nem sequer nada. Não poderíamos chamá-los de fantasmas de quantidades mortas?

E concluía:

Newton usou os infinitésimos assim como nas construções fazemos uso de andaimes, os quais abandonamos após o término da obra

Muitos matemáticos trabalharam para tentar contornar as críticas de Berkeley. A Escola Axiomática de David Hilbert produziu a seguinte declaração formal:

Sejam x e y dois números muito pequenos; o primeiro escolhido de tal modo que para todos os valores de h menor que y, e para qualquer valor de t, a razão…

Em 1966, Abraham Robinson publicou a Análise Non-Standar. Com o cálculo dos hiper-reais e o operador St., Robinson conseguiu manter os tais “andaimes” até o final do cálculo. Esse método serviu de inspiração para a Teoria do Operador Autodestrutivo desenvolvida pelo professor Aguinaldo P. Ricieri.

Nesse artigo, vou demonstrar como se deriva utilizando os Fluxos e o limite e apresentar o problema levantando por Berkeley. Em seguida, vou demonstrar como o operador autodestrutivo resolve o problema do “fantasma”.

O Método dos Fluxos

O gráfico abaixo é a forma mais didática de interpretar um fluxo:

Fique atento a esse Δx que apareceu. As relações trigonométricas produzem o limite genérico:

limΔx→0 [f(x + Δx) – f(x)] ÷ Δx

Para derivar uma função pelo método dos fluxos, basta aplicar a função objetivo no limite acima. Vamos ver um exemplo:

1. Função objetivo:

f(x) = 3x2 + 5x + 8

2. Substituindo no limite:

limΔx→0 [3(x + Δx)2 + 5xΔx + 8 – (3x2 + 5x + 8)] ÷ Δx

3. Fazendo a álgebra:

limΔx→0 [3Δx2 + 6xΔx + 5Δx] ÷ Δx

4. Aplicando o limite, encontramos a primeira derivada da função:

f'(x) = 6x + 5

O processo acima pode ser descrito em 5 passos. O problema está no passo 4:

Passo 1: função objetivo

f(x) = 3x2 + 5x + 8

Passo 2: dá-se um incremento Θ à função (aqui começa o problema)

f'(x) = [f(x + Θ) – f(x)] ÷ Θ

Passo 3: executa-se a álgebra de f'(x)

f'(x) = 3Θ + 6x + 5

Passo 4: Θ é muito pequeno, portanto, desprezível (esse é o problema)

f'(x) = 30 + 6x + 5

Passo 5: obtém-se a derivada da função

f'(x) = 6x + 5

O Método dos Operadores Autodestrutivos

O método dos operadores autodestrutivos resolve o problema do tal “fantasma” ou “andaime”, que é o alicerce da forma clássica de se resolver derivadas. Algo que chama a atenção na estrutura do operador autodestrutivo é o “operador amilcarniano” ou “símbolo de Amílcar” . Esse símbolo foi nomeado em homenagem a um colega de departamento do professor Ricieri no ITA. Foi meio difícil achar o caracter referente a esse símbolo para colocar aqui no artigo. Ele designa a desconexão das funções pertencentes a super-função. A inspiração para aquele símbolo veio da capa do famoso álbum do Pink Floyd, The Dark Side of The Moon. Na capa, vê-se um prisma separando a luz branca em suas componentes:

Propriedade 1: o operador autodestrutivo desacopla uma super-função de suas funções constituintes

R*f(x) f*(x + R*)

Propriedade 2: o operador R* operando ele mesmo dá como resultado 0. É daí que vem o nome do operador autodestrutivo

R*R* = 0

Propriedade 3: o operador autodestrutivo atuando em um número resulta o próprio número

R*N = N

O objetivo do operador autodestrutivo é apresentar todas as derivadas sem perda do que foi utilizado para chegar a elas. Vamos ver um exemplo.

1. Função objetivo:

f(x) = 3x2 + 5x + 8

2. Aplicando o operador R*:

R*f(x) R*(3x2 + 5x + 8)
R*f(x) R*(3x2) + R*(5x) + R*8

3. Aplicando a propriedade 3:

R*f(x) R*(3x2) + R*(5x) + 8

4. Aplicando a propriedade 1:

R*f(x) 3(x2 + R*2x + R*R*) + 5(x + R*) + 8

5. Aplicando a propriedade 2:

R*f(x) 3(x2 + R*2x + 0) + 5(x + R*) + 8
R*f(x) 3x2 + R*6x + 5x + R*5 + 8

6. Colocando em primeiro lugar os termos já operados por R*, obtemos a função original:

R*f(x) 3x2 + 5x + 8 + R*6x + R*5
R*f(x) f(x) + R*6x + R*5

7. Aplicando a propriedade 3:

R*f(x) f(x) + R*6x + 5

8. Aplicando a propriedade 1:

R*f(x) f(x) + 6(x + R*) + 5
R*f(x) f(x) + 6x + R*6 + 5

9. Colocando em primeiro lugar os termos já operados por R*, obtemos a primeira derivada:

R*f(x) f(x) + 6x + 5 + R*6
R*f(x) f(x) + f'(x) + R*6

10. Aplicando a propriedade 3:

R*f(x) f(x) + f'(x) + 6

11. Colocando em primeiro lugar os termos já operados por R*, obtemos a segunda derivada:

R*f(x) f(x) + f'(x) + f”(x)

Ou seja:

f(x) = 3x2 + 5x + 8
f'(x) = 6x + 5
f”(x) = 6

O método do operador autodestrutivo pode ser descrito em 5 passos. O funcionamento desse método dispensa a gambiarra do incremento descartável. O passo 4 elimina o elemento que não está em função de x utilizando as próprias propriedades do operador:

Passo 1: função objetivo

f(x) = 3x2 + 5x + 8

Passo 2: aplicar o operador autodestrutivo R*

R*f(x) = f(x + R*)

Passo 3: executa-se a álgebra

R*f(x) R*(3x2 + 5x + 8)
R*f(x) R*(3x2) + R*(5x) + R*8

Passo 4: aplica-se a propriedade 2

R*R* = 0

Passo 5: obtém-se a primeira derivada da função

R*f(x) f(x) + R*f'(x)
R*f(x) 6x + 5 + R*6

Referências

1. RICIERI, Aguinaldo P. Cálculo sem Limites – Operador Autodestrutivo. Editora Prandiano, São Paulo, 1992.

2. SANTOS, João Luiz dos. Uma Retrospectiva Histórica do Cálculo Diferencial. INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DO RIO GRANDE DO SUL. Disponível em: [http://rodrigomat2004.pbworks.com/w/file/fetch/89732927/grupo8_joao.pdf]. Acesso em 08 jan. 2020.

Spring Boot: Persistência com MongoDB

Faz alguns meses que tenho olhado com bastante interesse para o Spring Boot. Ele realmente faz com que fiquemos mais produtivos ao abstrair, dentre outras coisas, a camada de persistência. O Spring Data atende os padrões JPA e JDBC e também oferece módulos para integração com MongoDB, Cassandra, Elasticsearch e outros. Vamos entender como integrar o Spring Boot ao MongoDB por meio do Spring Data. Primeiro, vá no site Spring Initializr e configure um projeto Maven com os seguintes módulos:

1. Web

2. Devtools

3. Spring Data MongoDB

Baixe o projeto e adicione-o ao seu IDE. O POM ficou assim:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.1.9.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>

   <groupId>br.com.exemplo</groupId>
   <artifactId>pessoa</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Pessoa</name>
   <description>Cadastro de pessoas</description>

   <properties>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-mongodb</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
         <scope>runtime</scope>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

Nos conectaremos ao banco pessoa que configuramos em outro artigo na porta 27018. Adicione as credenciais do usuário e os dados de conexão no application.properties:

server.port=8082
server.servlet.context-path=/pessoa
#mongodb
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27018
spring.data.mongodb.database=pessoa
spring.data.mongodb.username=rodrigo
spring.data.mongodb.password=123456
#logging
logging.level.org.springframework.data=debug
logging.level.=error

Defina a entidade Pessoa. Note que essa entidade é muito parecida com uma entidade JPA. Uma das maiores diferenças é a anotação @Document no lugar o @Table:

import java.math.BigInteger;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Document(collection = "pessoas")
public class Pessoa {
   @Id
   private BigInteger _id;
   
   @Field("codigo")
   private Long codigo;

   @Indexed
   @Field("nome")
   private String nome;

   // getters e setters
}

Defina uma interface repositório que estenda a interface MongoRepository. Tal qual a interface do repositório JPA (JpaRepository), os CRUDs já estão definidos e não será necessário código algum para um uso básico. Porém, vamos adicionar o método findByCodigo, que é um Query Method que utiliza a “mágica” dos findBy:

import java.util.Optional;
import org.springframework.data.mongodb.repository.MongoRepository;
import br.com.exemplo.pessoa.model.Pessoa;

public interface PessoaRepository extends MongoRepository<Pessoa, Long> {
   public Optional<Pessoa> findByCodigo(Long codigo);
}

Cabe ressaltar que você deve tomar cuidado com o findById se você definiu uma propriedade id no seu modelo. O MongoDB cria um campo _id automaticamente e atribui a ele um SHA-1 para que o documento seja único. Vamos criar um serviço para expor explicitamente os métodos implícitos no repositório:

import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import br.com.exemplo.pessoa.dao.PessoaRepository;
import br.com.exemplo.pessoa.model.Pessoa;

@Service
public class PessoaService {
   @Autowired
   private PessoaRepository repository;

   public void salvar(Long codigo, String nome) {
      Pessoa pessoa = new Pessoa();
      pessoa.setCodigo(codigo);
      pessoa.setNome(nome);
      repository.save(pessoa);
   }

   public List<Pessoa> findAll() {
      return repository.findAll();
   }

   public long count() {
      return repository.count();
   }

   public void delete(Pessoa pessoa) {
      repository.delete(pessoa);
   }

   public Optional<Pessoa> findByCodigo(Long codigo) {
      return repository.findByCodigo(codigo);
   }
}

Defina agora o seu controller:

import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import br.com.exemplo.pessoa.model.Pessoa;
import br.com.exemplo.pessoa.service.PessoaService;

@RestController
@RequestMapping(path = "/v1/pessoas")
public class PessoaWSController {
   @Autowired
   private PessoaService service;
 
   @GetMapping(value = "/buscar/{codigo}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
   @ResponseStatus(HttpStatus.OK)
   public ResponseEntity<?> buscar(@PathVariable("codigo") Long codigo) {
      Optional<Pessoa> pessoa = service.findByCodigo(codigo);
      return ResponseEntity.ok(pessoa.get());
   }
}

Por último, execute a aplicação:

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class PessoaWSApplication {
   public static void main(String[] args) {
      SpringApplication.run(PessoaWSApplication.class, args);
   }

   @Bean
   public CommandLineRunner commandLineRunner() {
      return args -> {
         System.out.println("====================");
         System.out.println("========SUBIU=======");
         System.out.println("====================");
      };
   }
}

Verifique se ao acessar a URL abaixo, você obteve o retorno esperado:

http://localhost:8082/pessoa/v1/pessoas/buscar/1

{
   _id: 2.898714477621201e+28,
   codigo: 1,
   nome: "Pedro"
}

Referências

1. MKYONG. Spring Boot + Spring Data MongoDB example. Mkyong.com. Disponível em: [https://www.mkyong.com/spring-boot/spring-boot-spring-data-mongodb-example/]. Acesso em 21 out. 2019.

2. NERI, Emmanuel. Utilizando MongoDB com Spring Data e Spring Boot. Emmanuel Neri. Disponível em: [https://emmanuelneri.com.br/2017/04/17/utilizando-mongodb-com-spring-data-e-spring-boot/]. Acesso em 21 out. 2019.

Conto: Uma Lenda Árabe

Diz uma linda lenda árabe que dois amigos viajavam pelo deserto e em um determinado ponto da viagem, discutiram. Um deles, ofendido, sem nada a dizer, escreveu na areia:

“Hoje, meu melhor amigo me bateu no rosto.”

Seguiram e chegaram a um oásis onde resolveram banhar-se. O que havia sido esbofeteado começou a afogar-se sendo salvo pelo amigo. Ao recuperar-se pegou um estilete e escreveu numa pedra:

“Hoje, meu melhor amigo salvou-me a vida.”

Intrigado, o amigo perguntou:

– Por que depois que te bati, você escreveu na areia e agora que te salvei escreveu na pedra?

Sorrindo, o outro amigo respondeu:

– Quando um grande amigo nos ofende, deveremos escrever na areia onde o vento do esquecimento e do perdão se encarregam de apagar; porém, quando nos faz algo grandioso, deveremos gravar na pedra da memória do coração onde vento nenhum do mundo poderá apagar.

Referências

1. AVELLAR, Valter. Lenda Árabe. Mensagem do Dia. Disponível em: [https://mensagensavellar.wordpress.com/2019/06/25/lenda-arabe/]. Acesso em 08 jan. 2020.

Categorias:Filosofia Tags:, ,

Bouncy Castle: Como Ler as Informações de um Certificado Digital

Bouncy Castle é uma coleção de APIs de criptografia para Java e C#. Ele oferece um provedor para JCE (Java Cryptography Extension) e JCA (Java Cryptography Architecture).

Antes de integrarmos o Bouncy Castle ao nosso projeto, precisamos nos certificar de que os arquivos da unlimited strength jurisdiction policy estão configurados. A instalação padrão do Java é limitada no que diz respeito à força das funções criptográficas devido às políticas que proíbem o uso de chaves com um tamanho que exceda certos valores como 128 para criptografia do tipo AES (Advanced Encryption Standard).

Baixe os arquivos da política e descompacte em algum lugar:

local_policy.jar
US_export_policy.jar

Substitua os arquivos do diretório {JAVA_HOME}/lib/security por aqueles que você descompactou. Após essa preparação do ambiente, passemos para nosso projeto. Para integrar o Bouncy Castle ao seu projeto, adicione as dependências abaixo ao POM:

<dependency>
   <groupId>org.bouncycastle</groupId>
   <artifactId>bcmail-jdk16</artifactId>
   <version>1.46</version>
</dependency>
<dependency>
   <groupId>org.bouncycastle</groupId>
   <artifactId>bcprov-jdk16</artifactId>
   <version>1.46</version>
</dependency>

Se você estiver utilizando o JBoss, não esqueça de cadastrar o módulo lá na instalação do JBoss e incluir a dependência no arquivo jboss-deployment-structure.xml do seu projeto:

<jboss-deployment-structure>
   <deployment>
      <dependencies>
         <module name="org.bouncycastle"/>
      </dependencies>
   </deployment>
</jboss-deployment-structure>

Crie um arquivo p7b para que leiamos o certificado contido lá. Vamos fazer um exemplo para retornar o subject do certificado, que é apresentado como um X500Principal, que é uma classe que representa a informação como nomes distintos assim:

CN=MARIO DA SILVA:12345678912,
OU=Autenticado por Alguma AC,
OU=(EM BRANCO),
OU=RFB e-CPF A3,
OU=Secretaria da Receita Federal do Brasil - RFB,
O=ICP-Brasil,
C=BR

O código fonte fica assim:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class CertificateReader {
   public String readSubject(String p7bPath) 
    throws CertificateException, FileNotFoundException{
      Security.addProvider(new BouncyCastleProvider());
      CertificateFactory certFactory = 
         CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
      X509Certificate certificate = 
         (X509Certificate) certFactory.generateCertificate(new FileInputStream(p7bPath));
      return certificate.getSubjectX500Principal().getName();
   }
}

Referências

1. COSGRIFF, Andrew J. X.509 Public Key Certificate and Certification Request Generation. Bouncy Castle Wiki – Java APIs 1.X. Disponível em: [http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation]. Acesso em 11 out. 2019.

2. PASZTOR, Janos. Working with Certificates in Java. Janos Pasztor Blog. Disponível em: [https://pasztor.at/blog/working-with-certificates-in-java]. Acesso em 11 out. 2019.

3. PROGRAMCREEK. Java Code Examples for org.bouncycastle.x509.X509V1CertificateGenerator.setSignatureAlgorithm. Program Creek. Disponível em: [https://www.programcreek.com/java-api-examples/?class=org.bouncycastle.x509.X509V1CertificateGenerator&method=setSignatureAlgorithm]. Acesso em 11 out. 2019.

4. KE, Pi. Different types of keystore in Java — BKS. Pixels Tech. Disponível em: [https://www.pixelstech.net/article/1467528503-Different-types-of-keystore-in-Java%E2%80%94-BKS]. Acesso em 11 out. 2019.

Git: Como Realizar um Cherry Picking

Às vezes, um merge pode se tornar muito complexo devido às características das alterações contidas nos commits. Pode ser também que um determinado commit intermediário de um branch também deva estar presente em outro branch. Nesses cenários, um merge convencional não é viável. Para trazer um commit ou um conjunto de commits de um branch para outro, o git disponibiliza o cherry-pick. Suponha que você queira trazer o commit 048c181 do branch develop para o branch feature:

git checkout feature
git cherry-pick 048c181

Perceba que não precisamos informa de que branch é esse commit porque o git atribui um ID único para cada commit. Agora, suponha que você queira trazer todos os commits do intervalo [048c181..5b9cdbd]:

git cherry-pick 048c181..5b9cdbd

Cuidado: o comando acima descarta o commit 048c181 – intervalo aberto no início. Para incluir o commit 048c181, é necessário adicionar o operador “^”:

git cherry-pick 048c181^..5b9cdbd

Para abortar um cherry-pick, basta rodar o comando novamente com o parâmetro –abort da mesma forma que fazemos com os comandos merge e rebase:

git cherry-pick --abort
git rebase --abort
git merge --abort

Alternativa

É possível emular um cherry picking com merge utilizando a estratégia ours. Com essa estratégia, em caso de conflito, a versão em que estamos trabalhando (our), será utilizada em detrimento da remota (theirs):

git checkout feature
git merge -s ours 048c181

Referências

1. TOLLMAN, Zack. Cherry Picking a Range of Commits with Git. tollmanz.com. Disponível em: [https://www.tollmanz.com/git-cherry-pick-range/]. Acesso em 19 nov. 2019.

2. BITBUCKET. Git Merge Strategy Options and Examples. Bitbucket Tutorials. Disponível em: [https://www.atlassian.com/git/tutorials/using-branches/merge-strategy]. Acesso em 19 nov. 2019.

3. GIT. Merge Strategies. git. Disponível em: [https://git-scm.com/docs/merge-strategies]. Acesso em 19 nov. 2019.

4. ______. Cherry Pick. git. Disponível em: [https://git-scm.com/docs/git-cherry-pick]. Acesso em 19 nov. 2019.

Como Eliminar Sessões no Oracle

O banco de dados Oracle mantém conexões inativas durante algum tempo, pois há a possibilidade de que a mesma aplicação que motivou a criação do objeto de conexão solicite novamente acesso ao banco de dados. Os pools de conexão das aplicações, como o do JBoss, têm formas de garantir a integridade da conexão antes de repassá-la para a aplicação. Depois que uma conexão é utilizada pela aplicação, ela é devolvida para o pool. Quando gerenciamos o pool manualmente, também temos que liberar a conexão manualmente. Se você utiliza um servidor de aplicação que dá suporte à JTA e oferece um pool de conexões, mas você ainda assim utiliza frameworks de aplicação e de persistência, podem ocorrer problemas que impeçam que uma conexão seja devolvida ao pool.

Nos cenários apresentados e agravados por pools de conexões mal dimensionados e muitas aplicações acessando o mesmo banco de dados, pode ser que o banco de dados não tenha tempo de matar as sessões inativas. Nesses cenários, você terá que matar as conexões manualmente. O Oracle disponibiliza as informações das conexões e dos processos que as utilizam nas tabelas v$Session e v$Process. Vamos fazer uma consulta que exibe as sessões inativas à mais de 600 segundos:

SELECT S.USERNAME,
     S.OSUSER,
     S.SID,
     S.SERIAL#,
     P.SPID,
     S.STATUS,
     S.MACHINE,
     S.PROGRAM,
     TO_CHAR(S.LOGON_TIME,'DD-MON-YYYY HH24:MI:SS') AS LOGON_TIME
FROM v$session S
INNER JOIN v$process P
ON S.PADDR = P.ADDR
WHERE S.STATUS = 'INACTIVE'
AND S.USERNAME NOT IN ('SYS', 'SYSMAN', 'DBSNMP')
AND S.LAST_CALL_ET > 600

Sobre a coluna “LAST_CALL_ET”:

1. Se o status é ACTIVE, a coluna armazena o tempo em segundos desde a ativação da sessão;

2. Se o status é INACTIVE, a coluna armazena o tempo em segundos desde a inativação da sessão.

Com essas informações podemos matar uma determinada seção informando as colunas SID e SERIAL#:

ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; 

Você também pode fazer tudo isso em uma query só:

SELECT 'ALTER SYSTEM KILL SESSION  ''' || S.SID || ',' || S.SERIAL# || ''' IMMEDIATE; '
FROM v$session S
INNER JOIN v$process P
ON S.PADDR = P.ADDR
WHERE S.STATUS = 'INACTIVE'
AND S.USERNAME NOT IN ('SYS', 'SYSMAN', 'DBSNMP')
AND S.LAST_CALL_ET > 600

Referências

1. COLOMBO, Fabrício. Consultando e eliminando sessões ativas no Oracle. Fabricio DEV. Disponível em: [http://fabriciodev.blogspot.com/2012/03/consultando-e-eliminando-sessoes-ativas.html]. Acesso em 19 nov. 2019.

2. POLI, Guilherme. Script para matar sessões inativas. Oracle Mais. Disponível em: [http://oraclemais.blogspot.com/2012/01/script-para-matar-sessoes-inativas.html]. Acesso em 19 nov. 2019.

Categorias:banco de dados Tags:,