Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are addBatch() and executeBatch() thread-safe?

Can i call executeBacth from a thread while another one keeps calling addBatch() on the same Statement ( or PreparedStatement ) object?

Update: Does anyone have exprerience with this issue? 'cause i get incorrect results. Not all updates i added to the the batch is executed.

like image 331
palindrom Avatar asked Oct 02 '09 14:10

palindrom


People also ask

Does executeBatch delete batch?

The statement's batch is reset to empty once executeBatch returns. Although this is specified in a section called 'Successful Execution', it is also the intended behaviour for unsuccessful execution. In short, when you call executeBatch() the current batch of statements is submitted to the database server and cleared.

What is a thread safe resource?

Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously. Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions.


1 Answers

I would take a step back and deeply reconsider the design. Why on earth would you like to share the same Statement (and thus implicitly also the Connection) between two threads?

The normal JDBC practice is that you should acquire and close the Connection, Statement and ResultSet in the shortest possible scope. That is, inside the very same method block. Here's a basic example:

public void update(List<Item> items) throws SQLException {
    Connection connection = null;
    PreparedStatement statement = null;
    try {
        connection = database.getConnection();
        statement = connection.prepareStatement(sql);
        for (Item item : items) {
            statement.setObject(1, item.getSomething());
            statement.addBatch();
        }
        statement.executeBatch();
    } finally {
        if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
        if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
    }
}

If all you want is just improving connecting performance, then use a connection pool. For example C3P0. But certainly do not share expensive DB resources among threads! This way you also don't need to worry about threadsafety. That's an implementation detail.

Oh, if that's not clear yet: you will not improve database performance by sharing the same statement and connection among multiple threads. Even worse, it would only slowdown and you'll run into threadsafety issues at both the Java and the Database side.

like image 196
BalusC Avatar answered Sep 23 '22 13:09

BalusC