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.