Czy standardowy sterownik JDBC MySQL jest bezpieczny dla wątków? W szczególności chcę użyć pojedynczego połączenia we wszystkich wątkach, ale każda instrukcja będzie używana tylko w jednym wątku. Czy istnieją pewne scenariusze, które są bezpieczne, a inne nie? Jakie masz doświadczenie?Czy wątki MySQL/JDBC są bezpieczne?
Odpowiedz
Transakcje są uruchamiane/zatwierdzane dla połączenia. Chyba, że robisz jakieś bardzo konkretne rzeczy (nie mogę naprawdę wymyślić przykładu, w którym byłoby to uzasadnione, aby być szczerym), lepiej jest z pulą połączeń i połączeniem na wątek.
Zastanawiam się, czy może istnieć przypadek użycia, w którym chciałbyś zrobić jakiś algorytm fork/join (por. Http://www.ibm.com/developerworks/java/library/j-jtp11137.html), ale całkowicie wewnątrz jedna transakcja, więc możesz otworzyć połączenie i rozpocząć transakcję w wątku początkowym, przekazać to do wszystkich executorów zadań, a następnie zatwierdzić w wątku początkowym po zakończeniu wszystkich dołączeń? –
Przykład: przesyłanie strumieniowe danych za pomocą 'load data local infile', do więcej niż jednej tabeli, w której dane mają wzajemne relacje i nie może być taniej iterowane ponad dwa razy. –
Jeśli autocommit = 1, to jest bardzo prawdopodobne, że wiele wątków ma to samo połączenie, pod warunkiem, że dostęp do połączenia jest zsynchronizowany. Jeśli autocommit = 0, będziesz musiał kontrolować dostęp do połączenia za pomocą pewnego rodzaju muteksów, aż do zatwierdzenia.
O ile nie ma absolutnie żadnych ograniczeń co do liczby połączeń, jakie może mieć aplikacja, puli połączeń może być bardziej opłacalną alternatywą.
Na podstawie mojego ostatniego doświadczenia, obiekt Connection
nie jest bezpieczny dla wątków w łączniku/J 5.1.33.
Natknąłem się na sytuację impasu opisaną w bug 67760. Nie wiem, czy jest to błąd, ale jedna rozsądna rada z dyskusji było:
[12 grudnia 2012 20:33] Todd Farmer
Proszę nie używać pojedynczego obiektu Connection w wielu wątków bez właściwa synchronizacja. Złącze/J - i co ważniejsze, protokół klient-serwer MySQL - nie pozwala na równoczesne operacje przy użyciu tego samego obiektu Connection. Jeśli obiekt połączenia musi być współużytkowany przez wątki, obowiązkiem autora kodu aplikacji jest zapewnienie prawidłowego serializowania operacji.
FYI, ten błąd został naprawiony teraz w 5.1.37. – Archie
".. Kiedy możesz współdzielić połączenie między wątkami (szczególnie, jeśli każdy wątek ma własne oświadczenie), zazwyczaj nie jest to dobry pomysł. Interfejs API JDBC nie jest tak naprawdę zaprojektowany do używania w sposób zapewniający wątek , a większość połączeń JDBC (w tym MySQL) może przetwarzać tylko jedno zapytanie naraz. "http://forums.mysql.com/read.php?39,171022,171195#msg-171195 – Tim
@Tim, Tak, Widziałem post wcześniej. Nie zagłębia się jednak w szczegóły dotyczące ewentualnych problemów, więc czułem, że byłoby ciekawie usłyszeć o doświadczeniach innych ludzi. Ponadto czułem, że jest to poprawne pytanie, które należało do bazy pytań o przepełnienie stosu. Możesz dodać ten link jako odpowiedź. :) –
Rozważ skorzystanie z puli połączeń. –