- Este tópico contém 3 respostas, 2 vozes e foi atualizado pela última vez 6 anos, 8 meses atrás por José Laurindo Chiappa.
-
AutorPosts
-
14 de março de 2018 às 12:14 am #109236MottaParticipante
Lock que previna SELECT
A situação é seguinte :
Uma aplicação ERP (Totvs) com diversas tabelas
Todas estas tabelas usam como chave primária
um campo padrão
R_E_C_N_O_A aplicação (creio) cria um novo registro
com um
select max(R_E_C_N_O_)+1Preciso porém que uma package plsql
crie registros em algumas destas tabelas
mas ao concorrer com o ERP ocorrem erros
de ORA-00001: restric?o exclusivaMinha pergunta é :
Existe alguma síntaxe em que seja possível
“lockar” o max(R_E_C_N_O_) no caso
de uma tabela específica.A ideia é ter um “wait” e não permitir
que a aplicação ERP e a package tenham
o mesmo R_E_C_N_O_ futuro.Lembro que não tenho como mudar o ERP
Tudo deveria ficar na package PLSQLE claro minimizando a possibilidade
de DEADLOCKs14 de março de 2018 às 8:20 pm #109241José Laurindo ChiappaModeradorBom, primeiro eu bateria na cara de quem programou um SELECT MAX pra encontrar o último valor de uma coluna, IGNORANDO que o RDBMS é MULTIUSUÁRIO POR DEFINIÇÃO : nada impede que um segundo depois que vc obteve o valor do MAX alguma outra sessão vá lá na tabela e INSIRA um registro a mais, tornando INÚTIL o resultado do teu SELECT MAX…. É o caso TÍPICO para o qual foram INVENTADAS as sequences , elas te ASSEGURAM 100% que o valor recebido é ÚNICO, independente do que outras sessões fizerem… A DESVANTAGEM das sequences é que elas não te garantem uma sequência numérica Rigorosamente Contínua : cada número ofertado pela SEQUENCE é único MAS caches, rollbacks e algumas situações do tipo PODEM te dar números não exatamente contínuos, podem haver GAPs… Num caso assim, o procedimento Correto seria o sistema ter uma tabela onde se guarda o último valor e cada sessão/transação inserindo registros bloqueia essa tabela, ou coisa assim…
Muito bem, isso posto E estando entendido que estamos GAMBIARRANDO porque os zémanés do tal ERP não seguiram a Recomendação/best practices de programação no Oracle e não tem como vc usar sequences nem tabela de valor (simulando sequences), Te respondendo :
– no RDBMS Oracle (e na Esmagadora MAIORIA dos RDBMSs) não há como lockar uma COLUNA apenas : vc locka um REGISTRO ou LOCKA A TABELA TODA, ponto….
– especificamente no RDBMS Oracle, os locks a nível de tabela NUNCA impedem os SELECTs, e um SELECT ‘normal’ nunca locka nada… Isso é uma característica FUNDAMENTAL do Oracle, blocks não impedem LEITURAS e LEITURAS não CAUSAM blocks… Em outros RDBMSs, pra não ter leitura ‘suja’ (ie, não ler registros que estejam sendo alterados/inseridos) realmente o SGBD aplica LOCKs mas no caso do Oracle não é assim,…
O que vc pode ter no Oracle que ‘impede’ um SELECT é um lock a nível de REGISTRO, aí isso impediria a leitura de registros que estivessem lockados SE o SELECT interessado em ler os registros lockados faça um SELECT nnn FROM tabela WHERE condiçãoderegistros FOR UPDATE…=> NO seu caso, ao que entendo o ERP não usa sequences pra obter o valor-chave E na hora de buscar o próximo valor chave ele vai na tabela e faz um simples SELECT MAX(coluna) FROM tabela, sem lockar nada, né ? Nessas condições imho a sua alternativa única seria fazer um LOCK TABLE nessa tabela, pois aí vc tem CERTEZA que eunquanto esse lock não for liberado pela sua rotina NENHUMA OUTRA TRANSAÇÂO de outros usuários inseriu novos dados e portanto teu SELECT MAX ** realmente ** tá retratando a verdade…
[]s
Chiappa
14 de março de 2018 às 10:17 pm #109242MottaParticipanteChiappa , primeiro grato por entender a encrenca e não dar sugestões de alterar o ERP.
Segundo grato por confirmar a minha suspeita que a única solução seria mesmo o LOCK TABLE.
Valeu.
14 de março de 2018 às 11:27 pm #109243José Laurindo ChiappaModeradorSim : fiz questão de EXPLICITAR que estamos gambiarrando justamente pelo fato do ERP ter feito caquinha E em tese ser inviável alterar o tal ERP : nem de longe esse tipo de coisa como lock de tabelas é recomendável – o que fizemos aqui foi tampar o nariz e gambiarrar, repito mas é que temos pra hoje, nessas condições…
Só uma última obs : CONFIRME na Documentação e no Suporte Técnico do tal ERP que realmente, positivamente, não há outra maneira… Digo isso porque não é incomum vc ter uma tela de entrada de dados , uma Procedure ou algo assim no ERP que é o ponto ÚNICO de INSERT nas tabelas em questão : se isso existir, TALVEZ vc possa temporariamente substituir essa tela e/ou essa procedure por uma versão SUA customizada, que não permita INSERTs enquanto tua outra rotina está sendo executada, OU talvez temporariamente tirar o privilégio nessa tela/rotina enquanto a sua está rodando, digamos…. ERPs são famosos por ter coisas assim…
Mas é por aí : não existindo um ponto passível de alteração/configuração, só te resta o caminho de lockar a tabela inteira, sim…
[]s
Chiappa
-
AutorPosts
- Você deve fazer login para responder a este tópico.