I'm currently learning JDBC. And I try to update the product information and insert a log at the same time.
private void testTransaction() { try { // Get Connection Connection connection = ConnectionUtils.getConnection(); connection.setAutoCommit(false); // Execute SQL Product product = new Product(1, 4000d); productService.updateProduct(connection, product); Log log = new Log(true, "None"); logService.insertLog(connection, log); // Commit transaction connection.commit(); } catch (Exception e) { e.printStackTrace(); } finally { ConnectionUtils.closeConnection(); } } When using single thread, it would be fine.
@Test public void testMultiThread() { testTransaction(); } But When I using multi-thread, even start one thread, the process would terminate automatically.
@Test public void testMultiThread() { for (int i = 0; i < 1; i++) { new Thread(this::testTransaction).start(); } } After debugging, I found that it was Class.forName() function in ConnectionUtils cause this situation.
public class ConnectionUtils { static private String url; static private String driver; static private String username; static private String password; private static Connection connection = null; private static ThreadLocal<Connection> t = new ThreadLocal<>(); static { try { Properties properties = new Properties(); properties.load(new FileReader("src/main/resources/jdbcConnection.properties")); driver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); Class.forName(driver); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() { try { connection = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } finally { t.set(connection); } return connection; } } The process will terminate at Class.forName(). I found this by adding two print funcion before and after the statement. And only the former works.
System.out.println("Before"); Class.forName(driver); System.out.println("After"); The console only print the Before and doesn't show any exception information. I want to know that why multi-thread in java will cause this situation and how to solve this problem.