JDBC: Posso compartilhar uma conexão em um aplicativo de multithreading, e desfrutar de transações agradáveis?

votos
5

Parece que a maneira clássica para lidar com transações com JDBC é definir auto-commit a false. Isso cria uma nova transação, e cada chamada para cometer marca o início dos próximos transações. No aplicativo multithreading, eu entendo que é uma prática comum para abrir uma nova conexão para cada segmento.

Eu estou escrevendo um aplicativo de servidor multi-cliente baseado RMI, de modo que, basicamente, o meu servidor é perfeitamente gerando uma thread para cada nova conexão. Para lidar com as transações corretamente devo ir e criar uma nova conexão para cada um dos fios? não é o custo de uma arquitetura tão proibitivo?

Publicado 14/11/2008 em 03:00
fonte usuário
Em outras línguas...                            


3 respostas

votos
4

Sim, em geral, você precisa criar uma nova conexão para cada segmento. Você não tem controle sobre como o sistema operacional timeslices execução de threads (não obstante definir suas próprias seções críticas), para que você possa, inadvertidamente, ter vários segmentos tentando enviar dados para baixo que um tubo.

Observe o mesmo se aplica a quaisquer comunicações de rede. Se você tivesse dois segmentos tentando compartilhar um soquete com uma conexão HTTP, por exemplo.

  • Thread 1 faz um pedido
  • Thread 2 faz um pedido
  • Thread 1 lê bytes da tomada, sem querer ler a resposta do pedido rosca 2 de

Se você envolveu todas as suas transações em seções críticas e, portanto, bloquear quaisquer outros tópicos para uma inteira begin / commit ciclo, então você pode ser capaz de compartilhar uma conexão de dados entre threads. Mas eu não faria isso, mesmo assim, a menos que você realmente tem conhecimento inato do protocolo JDBC.

Se a maioria dos seus segmentos têm necessidade infrequente para conexões de banco de dados (ou nenhuma necessidade em tudo), você pode ser capaz de designar um segmento para fazer o seu trabalho de banco de dados, e tem outros tópicos fila seus pedidos para que um fio. Isso reduziria a sobrecarga de tantas conexões. Mas você vai ter que descobrir como gerenciar conexões por fio em seu ambiente (ou outra pergunta específica sobre isso em StackOverflow).

update: Para responder a sua pergunta no comentário, a maioria das marcas de banco de dados não suportam várias transações simultâneas em uma única conexão (InterBase / Firebird é a única exceção que eu saiba).

Seria bom ter um objeto de transação separada, e para ser capaz de iniciar e cometer várias transações por ligação. Mas os vendedores simplesmente não apoiá-lo.

Da mesma forma, APIs padrão independente de fornecedor, como JDBC e ODBC fazer a mesma suposição, que o estado da transação é meramente uma propriedade do objeto de conexão.

Respondeu 14/11/2008 em 03:17
fonte usuário

votos
1

É prática incomum para abrir uma nova conexão para cada segmento. Normalmente você usar um pool de conexão como c3po biblioteca.

Se você estiver em um servidor de aplicação, ou usando o Hibernate por exemplo, olhar a documentação e você vai encontrar como configurar o pool de conexão.

Respondeu 14/11/2008 em 03:25
fonte usuário

votos
1

O mesmo objeto de conexão pode ser usado para criar vários objetos de instrução e estas demonstrações objetos podem então usado por diferentes threads simultaneamente. A maioria dos bancos de dados modernos interligados por JDBC pode fazer isso. O JDBC é, portanto, capaz de fazer uso de cursores simultâneos como segue. PostgreSQL é nenhuma exceção aqui, ver, por exemplo:

http://doc.postgresintl.com/jdbc/ch10.html

Isso permite que o pool de conexão, onde a conexão são usados ​​apenas por um curto período de tempo, ou seja, criou o objeto declaração e, mas depois que voltou para a piscina. Esta partilha de tempo curto só é recomendado quando a conexão JDBC faz também paralelização de Operações de instruções, caso contrário, o pool de conexão normal pode mostrar melhores resultados. De qualquer forma o segmento pode continuar o trabalho com o objeto declaração e fechá-lo mais tarde, mas não a ligação.

1. Thread 1 opens statement   
3. Thread 2 opens statement
4. Thread 1 does something         Thread 2 does something
5. ...                             ...
6. Thread 1 closes statement       ...
                                7. Thread 2 closes statement

O acima só funciona no modo automático cometer. Se forem necessárias transações ainda não há necessidade de amarrar a transação a um fio. Você pode apenas particionar o pooling ao longo das transações que é tudo e usar a mesma abordagem que acima. Mas isso só é necessária não por causa de alguma limitação conexão de soquete, mas porque o JDBC, em seguida, equivale a identificação da sessão com o ID da transação.

Se eu me lembro bem deve haver APIs e produtos ao redor com um design menos simplista, onde teh ID da sessão e o ID da transação não são equiparados. Neste APIs você pode escrever seu servidor com um objeto de conexão de banco de dados único, mesmo quando ele faz transações. Terá que verificar e dizer-lhe mais tarde o que este APIs e produtos são.

Respondeu 02/10/2011 em 11:02
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more