Colocar a lógica de negócios em Procedimento Armazenado ou Não?

21

Sempre há um debate sobre o tópico - "Se a lógica de negócios deve ser inserida em Procedimento armazenado ou não?". Se decidirmos não usar a ferramenta ORM e não colocar a lógica de negócios no procedimento armazenado, onde colocaremos a lógica de negócios?

Nos meus aplicativos anteriores, sempre preferi colocar toda a lógica de negócios apenas em procedimentos armazenados. Em seguida, no código .NET, chamo esses procedimentos armazenados usando os blocos de aplicativos de acesso a dados. SQLHelper etc. Mas esse não pode ser o cenário o tempo todo. Então eu pesquisei no Google, mas acabei confuso .......

Alguma sugestão ...?

Pravin Patil
fonte
Sou tendencioso -> Procs armazenados sempre. Mas então eu sou tendenciosa. Esqueça a programação ágil, a triste realidade é que, no mundo dos negócios, as mudanças sempre acontecem ad-hoc e precisam ser feitas "imediatamente". Os procedimentos armazenados permitem isso. É um salva-vidas. Tentar fazer essas alterações através da base de código não seria viável.
Darknight
4
@ Darknight, Depende muito da sua plataforma e arquitetura para fazer uma declaração como essa. Não vejo por que a implantação de um procedimento armazenado em um banco de dados consome muito menos tempo do que, por exemplo, executar um script de compilação e implantação para criar um novo arquivo WAR, implantá-lo e reiniciar o servidor de aplicativos.
maple_shaft
7
Procedimentos armazenados - o tanque séptico da ciência da computação.
Mongus Pong 10/10
1
Procedimentos armazenados - apenas mais uma ferramenta como qualquer outra.
sam yi

Respostas:

15

Eu adotaria uma abordagem pragmática - historicamente, o principal 'benefício' de manter a lógica de negócios em procs armazenados é por razões de desempenho (arquitetura de 2,5 camadas), enquanto separar a lógica de negócios em uma camada de BLL (camada 3 / N) geralmente é mais limpa de uma perspectiva de manutenção e mais fácil de testar (simule / desconecte o acesso a dados).

No entanto, como os ORMS .NET habilitados para LINQ, como LINQ2SQL, EF e NHibernate, agora criam consultas SQL parametrizadas, nas quais os planos de consulta podem ser armazenados em cache, são escapados para a Injeção SQL, etc. mais convincente do que nunca, e a maioria dos SPROCs (especialmente os centrados em consultas) podem ser totalmente evitados. Os padrões de repositório no .NET normalmente expõem os parâmetros da árvore IQueryable / accept Expression, permitindo um tipo de acesso seguro e flexível às suas tabelas. (Pessoalmente, nas arquiteturas do tipo SOA, eu não exporia o IQueryable além da BLL, ou seja, suas camadas de Serviço e Apresentação devem funcionar com um conjunto de métodos bem definido. O motivo é que, caso contrário, você nunca poderá testar completamente o seu sistema e você ganhará '

No entanto, em um sistema de tamanho decente, sempre haverá algumas exceções, nas quais um código realmente intensivo em dados ainda precisa ser gravado como um Proc armazenado por motivos de desempenho. Nesses casos, eu manteria o SPROC e o exporia através do ORM, mas ainda assim exporia a função como um método de passagem na sua BLL.

StuartLC
fonte
1
+1 para facilitar a gravação de testes de unidade na camada do aplicativo, no entanto, as estruturas de teste de unidade de banco de dados automatizadas percorreram um longo caminho.
maple_shaft
14

Sendo um desenvolvedor java, minha preferência era colocar a lógica de negócios no BLL (controle de fonte fácil e agradável, familiaridade etc etc etc).

No entanto, depois de trabalhar para uma grande empresa com muitos aplicativos distribuídos usando diferentes tecnologias (C #, Java, Pick (não pergunte)), um benefício significativo do uso de procedimentos armazenados tornou-se aparente:

Os procedimentos armazenados podem ser compartilhados entre diferentes aplicativos .

NimChimpsky
fonte
Muito bom ponto
NoChance 10/10
1
Isso é muito verdadeiro, e nós o usamos com bons efeitos em nosso ambiente. No entanto, compartilhar código usando a camada de dados sempre me pareceu um pouco perigoso. Se você tem vários consumidores de uma determinada peça de lógica / dados, prefiro colocar um serviço na frente dele do que ter vários consumidores do mesmo banco de dados.
RationalGeek
2
Se você dividir a sua gestão de dados em bibliotecas, as bibliotecas também podem ser compartilhados entre diferentes aplicações teoricamente ...
glenatron
2
Eu concordo parcialmente. Todas essas tecnologias estão acessando o banco de dados diretamente; então você está usando procedimentos armazenados para compartilhar código comum entre eles. Você também pode resolver o mesmo problema com uma camada intermediária e ter soluções heterogêneas acessando sua camada intermediária em vez de seu banco de dados, e essa camada compartilha esse código.
Ekevoo
1
fyi, essa resposta é idiota, seis anos depois - apenas os dados entram no banco de dados. Se você colocar a lógica, terá muitos problemas na linha. Basta criar o microsserviço no idioma de sua escolha que acessa o banco de dados.
NimChimpsky
6

Nossa equipe tem uma regra simples aqui. Às vezes, é melhor resolver a lógica de negócios em T-SQL; às vezes, é mais fácil fazê-lo em c # (camada de negócios).

Portanto, temos uma solução pragmática: coloque onde se encaixa melhor. Eu sei que a teoria às vezes é muito rigorosa sobre isso ... mas isso é teoria :-)

gsharp
fonte
2
Certamente esta é a pior solução de todas? Como um desenvolvedor de manutenção sabe onde a lógica está armazenada? Eu imagino que, às vezes, ele também se arrasta para a camada de aplicativo ou, pior ainda, para a interface do usuário?
Paul T Davies
2
Não. É sempre na camada de negócios ou T-SQL. Descobrir onde a lógica está armazenada é provavelmente o menor problema em manutenção.
gsharp
O que acontece quando alguém se junta à equipe e você lhes diz essa regra? Como eles devem saber onde algo "se encaixa melhor"? Isso quase parece uma regra para mim. Muito subjetivo com base no indivíduo.
RationalGeek
3
Vamos lá pessoal, sério? Empregamos pessoas que têm um cérebro para pensar e que têm alguma experiência a bordo. Então .. ah sim, eles têm boca para perguntar e conversar. Posso dizer que nosso software precisa de manutenção muito baixa e os novos recursos podem ser implementados corretamente por quase todos da nossa equipe. Não pode estar errado o que fazemos.
gsharp
4
Realmente não vejo sentido usar mal o c # para coisas que o SQLServer pode fazer muito melhor e vice-versa.
gsharp
3

Existem vantagens e desvantagens de ambos (na minha opinião):

Os procedimentos armazenados podem se tornar um pesadelo se você não estiver usando algum tipo de controle de origem SQL (o que muitos lugares não fazem) e você tiver vários desenvolvedores trabalhando neles. Alguém pode alterar um procedimento armazenado e esquecer de atualizar o código que chama esse procedimento e, antes que você perceba, você acabou de criar e implantar um site que lançará exceções sem tratamento (incompatibilidade de contagem de parâmetros, etc.).

Por outro lado, os procedimentos armazenados permitem correções de erros mais rápidas em determinadas situações. Se houver um erro com um procedimento armazenado, você apenas o corrige e pronto. Uma correção de bug em um ORM requer uma reconstrução. Dependendo do seu processo de compilação, isso pode ser demorado / irritante.

AndrewC
fonte
+1 para a necessidade de controle de origem com procs armazenados, se você for usá-los intensamente. Muitos DBAs com os quais trabalhei são muito resistentes a essa idéia.
RationalGeek
2

Sempre colocamos nossa lógica de negócios na camada de lógica de negócios. Se você colocá-lo no Procedimento armazenado, ele será perdido quando você alterar seu RDBMS.

šljaker
fonte
16
A última coisa que muda é o RDBMS ;-)
gsharp
Então, isso significa que você limita o Procedimento armazenado a buscar, atualizar e inserir os dados ....?
Pravin Patil 10/10
1
Todo sistema grande que eu já vi, a realidade é que o banco de dados É o sistema. Linguagens de programação quase se tornam irrelevantes neste momento, apenas como o "front end". #
Darknight
2
@gsharp, isso nem sempre é verdade. Você pode querer adicionar outro RDBMS como o Oracle ou substituir completamente o existente. Ou, em alguns casos, você deseja substituir dados reais por dados fictícios.
šljaker
2
@ Esljaker, é claro que nem sempre é verdade. Mas é mais provável que o programa mude (reprojeto do software, novas linguagens de programação etc.) em vez do DB.
gsharp
2

"Lógica de negócios" é um termo um tanto vago. Quero dizer, não tem uma definição única. Uma regra prática é minimizar a comunicação entre as camadas quando possível. Portanto, você não precisa enviar o nome do cliente em branco ao servidor para verificá-lo antes de inserir uma linha.

Há casos em que uma regra é baseada em uma leitura de banco de dados. Digamos que você queira transferir dinheiro da Conta 1 para a Conta 2. Você precisa ler as duas contas, verificar se estão em bom estado e se o valor da Conta 1 é suficiente. Nesse caso, o servidor é um candidato melhor para esta regra porque o cliente (sendo o BL aqui) não precisa emitir 3 chamadas para a camada de banco de dados para esse processo.

Obviamente, se você precisar que sua solução seja independente do banco de dados, faça procs armazenados apenas para CRUD (se houver algum).

NoChance
fonte
1

A lógica deve estar sempre na BLL porque:

  • Pode ser testado corretamente
  • Quando o SQL 20XX se torna obsoleto e você precisa mudar para a versão mais recente, não é necessário reescrever seu código.
  • As pessoas não são tentadas a fazer alterações em tempo real (o que parece estar sendo apresentado como argumento para os SPs)
  • Os SPs, na minha experiência, são o maior ponto de erro do desenvolvedor, especialmente após algumas gerações de manutenção / alterações.

Acredito que deveria haver uma lei que afirma que, após um SP ter mais de X linhas, ele não funciona conforme o esperado.

Paul T Davies
fonte
O que há de errado com as mudanças em tempo real? Se houver um erro em um procedimento armazenado e ele for facilmente corrigido, corrija-o. É positivo, porque significa que você não precisa fazer um relançamento para algo trivial. Desde que as pessoas não comecem a mascarar erros no código alterando os procedimentos armazenados, não vejo problema algum.
AndrewC
Com mudanças dinâmicas, quero dizer coisas que não foram testadas e não seguem um procedimento formal de liberação. E sim, mudanças de sp para mascarar erros de código é algo que já vi bastante.
Paul T Davies
0

Criamos uma camada de serviços que contém toda a nossa lógica de negócios implementada no idioma escolhido e usamos apenas o banco de dados para consultas. Essa abordagem é um pouco exigida por nós, porque nosso objetivo é criar soluções COTS para entregar aplicativos com várias implementações de banco de dados. O Hibernate provou ser um salva-vidas para nós nessas circunstâncias.

Penso que a maior vantagem dessa abordagem, além da portabilidade do banco de dados, é que você pode encontrar todas as suas respostas em uma pesquisa.

Além disso, apesar de algumas das respostas de um fórum, tenho um amigo trabalhando para uma companhia de seguros da Fortune 100 que fez duas conversões de banco de dados em três anos porque o banco de dados de escolha para a empresa mudou.

Thom
fonte
0

Na minha experiência limitada, prefiro manter a integridade dos dados com procedimentos armazenados e outros recursos do banco de dados. Por exemplo, se eu estivesse implementando uma transferência de fundos entre duas contas, escreveria um procedimento armazenado. Acho valioso poder usar vários idiomas de aplicativos.

Kevin Cline
fonte