Нечто подобное происходит:
Поток 1: вызывает prepare()
, создает соединение, возвращает подготовленный оператор и оставляет prepare()
, поэтому другие потоки теперь могут вводить prepare()
Поток 1: начинает выполнение запроса
Поток 2: входит в подготовку и проверяет, что соединение в порядке - это то же соединение, которое созданный поток 1 использует и использует.
Поток 1: закрывает соединение
Поток 2: пытается вызвать prepareStatement для соединения, которое теперь закрыто
Вы должны исследовать использование пула соединений, который даст каждому потоку свое собственное соединение, котороевозвращается в пул, когда он «закрыт».