w przypadku korzystania z PreparedStatement z jednym wspólnym połączeniem bez puli, czy mogę odtworzyć instancję dla każdej operacji dml / sql, zachowując moc przygotowanych instrukcji?
Mam na myśli:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
zamiast:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
moje pytanie wynika z faktu, że chcę umieścić ten kod w środowisku wielowątkowym, czy możesz dać mi jakąś radę? dzięki
java
jdbc
prepared-statement
Stalowy pióropusz
źródło
źródło
sql
nie zmienia się z w pętli? jeśli to zapytanie nie zmienia się dla każdej iteracji pętli, to dlaczego tworzysz nowePreparedStatement
dla każdej iteracji (w pierwszym fragmencie kodu)? Czy jest jakiś powód, aby to robić?Odpowiedzi:
Drugi sposób jest odrobinę bardziej wydajny, ale znacznie lepszym sposobem jest wykonywanie ich partiami:
Jesteś jednak zależny od implementacji sterownika JDBC, ile partii można wykonać naraz. Możesz na przykład chcieć wykonywać je co 1000 partii:
Jeśli chodzi o środowiska wielowątkowe, nie musisz się tym martwić, jeśli uzyskasz i zamkniesz połączenie i instrukcję w najkrótszym możliwym zakresie w tym samym bloku metody zgodnie z normalnym idiomem JDBC przy użyciu instrukcji try-with-resources , jak pokazano w powyżej fragmentów.
Jeśli te partie są transakcyjne, chcesz wyłączyć automatyczne zatwierdzanie połączenia i zatwierdzać transakcję dopiero po zakończeniu wszystkich partii. W przeciwnym razie może to spowodować brudną bazę danych, gdy pierwsza seria partii zakończy się powodzeniem, a później nie.
źródło
inside the same method block
- masz na myśli, że każdy wątek będzie miał swój własny stos, a te połączenia i instrukcje są na stosie z jednej strony iz innego źródła danych, dadzą każdemu nowemu wywołaniu funkcji executeFunction (== każdy wątek) oddzielne wystąpienie połączenia. Czy dobrze cię rozumiem? ”Pętla w twoim kodzie to tylko nadmiernie uproszczony przykład, prawda?
Lepiej byłoby utworzyć
PreparedStatement
jedyny raz i używać go wielokrotnie w pętli.W sytuacjach, w których nie jest to możliwe (ponieważ zbytnio skomplikowało to przepływ programu), nadal korzystne jest użycie
PreparedStatement
, nawet jeśli używasz go tylko raz, ponieważ praca po stronie serwera (parsowanie kodu SQL i buforowanie wykonania plan), nadal będą zmniejszane.Aby rozwiązać problem, w którym chcesz ponownie użyć strony Java
PreparedStatement
, niektóre sterowniki JDBC (takie jak Oracle) mają funkcję buforowania: Jeśli utworzyszPreparedStatement
dla tego samego SQL w tym samym połączeniu, da ci to samo (buforowane ) instancja.O wielowątkowości: i tak nie sądzę, aby połączenia JDBC mogły być współużytkowane przez wiele wątków (tj. Używane jednocześnie przez wiele wątków). Każdy wątek powinien otrzymać własne połączenie z puli, użyć go i ponownie zwrócić do puli.
źródło