2010-05-10 9 views
2

Supposons que j'ai une table contenant des données valides. Je voudrais modifier ces données d'une certaine manière, mais je voudrais m'assurer que si des erreurs se produisent avec la modification, la table n'est pas changée et la méthode retourne quelque chose à cet effet. Par exemple, (c'est un peu un exemple stupide, mais il illustre le point donc supporter avec moi) suppose que je veux éditer toutes les entrées dans une colonne "nom" afin qu'ils soient correctement capitalisés. Pour une raison quelconque, je veux que TOUS les noms aient la bonne capitalisation, ou AUCUN d'entre eux d'avoir une bonne capitalisation (et l'état de départ de la table est que AUCUN d'entre eux ne le fait).Existe-t-il un bon moyen d'exécuter des instructions MySQL de manière atomique via JDBC?

Existe-t-il un moyen déjà mis en œuvre pour exécuter une mise à jour par lots sur la table et être assuré que, si l'une des mises à jour échoue, toutes les modifications sont annulées et la table reste inchangée?

Je peux penser à quelques façons de le faire à la main (bien que les suggestions sont les bienvenues), mais ce serait bien s'il y avait une méthode que je pouvais utiliser qui fonctionnerait de cette façon. J'ai regardé la commande java.sql.statement.executeBatch(), mais je ne suis pas convaincu par la documentation que ma table ne serait pas changée si elle échouait d'une manière ou d'une autre.

Répondre

8

je frappe celui-ci aussi lors du démarrage avec JDBC - il semblait voler en face de ce que je compris sur les bases de données et des garanties ACID.

Avant de commencer, assurez-vous que votre MySQL prend en charge les transactions storage engine. MyISAM ne supporte pas les transactions, mais InnoDB le fait.

Ensuite, assurez-vous de désactiver JDBC autoCommit - Connection.setAutoCommit(false), ou JDBC exécutera chaque instruction en tant que transaction séparée. Le commit sera une affaire de tout ou rien - il n'y aura pas de changements partiels. Ensuite, vous exécutez vos diverses instructions de mise à jour, et enfin appelez Connection.commit() pour valider la transaction.

Voir la Sun Tutorial pour plus de détails sur les transactions JDBC.

L'utilisation d'un lot ne change pas les garanties ACID - vous soit TRANSIGÉES ou que vous n'êtes pas! - Le traitement par lots concerne davantage la collecte de plusieurs instructions pour améliorer les performances.

+0

Un grand +1 pour le MyISAM par rapport à indice InnoDB. Ceci est trop souvent négligé. – BalusC

+0

Donc, juste pour être sûr ici, la bonne façon de faire les instructions de mise à jour serait via Statement.executeUpdate (...) un tas de fois, puis connection.commit() dans le bloc try, et connection.close() à l'intérieur du bloc d'arrêt(). Si une sorte d'exception était interceptée, ne pas appeler connection.commit() serait suffisant pour ne pas modifier la table, n'est-ce pas? – javanix

+1

C'est correct - la fermeture d'une connexion avec des transactions non validées annule la transaction. (Petit mais significatif changement - mettre connection.close() dans votre bloc finally, pas le bloc catch.) – mdma