Czesć mam problem z wątkami.
Kod poniej:
public class SQLFileQueryService {
@PersistenceContext
protected EntityManager entityManager;
@Autowired
private TransactionTemplate transactionTemplate;
private void executeSQLScript(String scriptName) {
transactionTemplate.execute(new TransactionCallback<>() {
@Override
public Void doInTransaction(TransactionStatus status) {
InputStream fis = this.getClass().getClassLoader().getResourceAsStream(scriptName);
String line;
try (BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
while ((line = br.readLine()) != null) {
// try to
entityManager.createNativeQuery(line).executeUpdate();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}
@Transactional
public void executeScriptsSql(String... scripts) {
// set some flag off
CompletableFuture<Void>[] tasks = new CompletableFuture[scripts.length];
IntStream.range(0, tasks.length).forEach(i -> tasks[i] = CompletableFuture.runAsync(() -> executeSQLScript(scripts[i])));
CompletableFuture.allOf(tasks).join(); // zatrzymuje główny wątek
/*
wait for all task
set some flag on
*/
}
}
próbowałem :
1 .CompletableFuture.allOf(tasks).join(); // zawiesza dzialanie wątków w transakcji
2. while (currentInUseThreadCount.get() > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
} // również zawiesza
Ogólnie to chciałem ominąć problem braku wsparcia wielowątkowości dla transactional w springu, stąd też pojawia się TransactionCallback
.
Moim celem jest wyłączenie flagi do sprawdzania kluczy ( by nie rzucało wyjątkami ), wrzucenie wszytkich sql'ek z plików i ponowne włączenie flagi.
Jakieś mądre wskazówki ?
Jeśli przepuszczę główny wątek ( nie będę czekał na dzieciaki odpaane w executeSQLScript
) to przy próbie odpalenia this.entityManager.createNativeQuery(enableFlagString).executeUpdate();
przez ostatni aktywny wątek entity manager jest nulowany.