and - java multithread pdf



È sicuro utilizzare un'istanza java.sql.Connection statica in un sistema con multithreading? (2)

il mio uso in thread di collegamento di oggetti statici è sicuro?

Assolutamente no!

In questo modo la connessione verrà condivisa tra tutte le richieste inviate da tutti gli utenti e quindi tutte le query interferiranno l'una con l'altra. Ma il threadsafety non è il tuo unico problema, la perdita di risorse è anche l'altro tuo problema. Stai mantenendo aperta una singola connessione durante tutta la vita dell'applicazione. Il database medio recupererà la connessione ogni volta che è stata aperta per troppo tempo, che di solito è tra 30 minuti e 8 ore, a seconda della configurazione del DB. Pertanto, se la tua applicazione web viene eseguita più a lungo, la connessione viene persa e non sarai più in grado di eseguire query.

Questo problema si applica anche quando tali risorse vengono considerate come una variabile di istanza non static un'istanza di classe che viene riutilizzata più volte.

Dovresti sempre acquisire e chiudere la connessione, l'istruzione e il set di risultati nel più breve ambito possibile , preferibilmente all'interno dello stesso blocco try-with-resources come dove stai eseguendo la query secondo il seguente idioma JDBC:

public User find(String username, String password) throws SQLException {
    User user = null;

    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement("SELECT id, username, email FROM user WHERE username=? AND password=md5(?)");
    ) {
        statement.setString(1, username);
        statement.setString(2, password);

        try (ResultSet resultSet = statement.executeQuery()) {
            if (resultSet.next()) {
                user = new User();
                user.setId(resultSet.getLong("id"));
                user.setUsername(resultSet.getString("username"));
                user.setEmail(resultSet.getString("email"));
            }
        }
    }       

    return user;
}

Notare che non si dovrebbe restituire un ResultSet qui. Se non si è ancora su Java 7, utilizzare un blocco try-finally cui si chiudono manualmente le risorse chiudibili nell'ordine inverso al momento dell'acquisto.

Se ti preoccupi di collegare le prestazioni, dovresti utilizzare invece il pool di connessioni. Questo è integrato in molti server applicativi Java EE e persino portacontatti barebone come Tomcat lo supporta. Basta creare un'origine dati JNDI nel server stesso e lasciare che la tua webapp lo DataSource come DataSource . È in modo trasparente già un pool di connessioni.

Guarda anche:

Sto eseguendo un'applicazione web su Tomcat. Ho una classe che gestisce tutte le query DB. Questa classe contiene l'oggetto Connection e i metodi che restituiscono i risultati della query.

Questo è l'oggetto di connessione:

private static Connection conn = null;

Ha solo un'istanza (singleton).

Inoltre, ho metodi che eseguono query, come la ricerca di un utente nel db:

public static ResultSet searchUser(String user, String pass) throws SQLException

Questo metodo utilizza l'oggetto Connection statica. La mia domanda è, è il mio uso in thread di Connection oggetto statico sicuro? Oppure può causare problemi quando molti utenti chiamano il metodo searchUser ?


Answer #1

Se stai eseguendo solo le query Select ( searchUser suona come se fosse solo la selezione dei dati) non ci saranno problemi, a parte la contesa del thread.

Per quanto ne so, una Connection può gestire solo una query alla volta, quindi utilizzando una singola istanza sarà essenzialmente serializzato l'accesso al database. Ma questo non significa necessariamente, è sempre sicuro accedere a un database come questo in un ambiente multi-thread. Potrebbero esserci ancora problemi se gli accessi concorrenti sono interleaving.





connection