From e5be03ce85300d99ad29859c89e02c5fc39ecfa8 Mon Sep 17 00:00:00 2001 From: Martin Goik <goik@hdm-stuttgart.de> Date: Thu, 8 Jan 2015 11:14:04 +0100 Subject: [PATCH] Grouping INSERTs into a single transaction --- .../mi/sda1/catalog2sql/DataInsert.java | 5 ++-- .../mi/sda1/catalog2sql/Xml2Rdbms.java | 27 +++++++++---------- .../handler/CatalogContentHandler.java | 23 +++++++++++----- .../mi/sda1/catalog2sql/messages.properties | 1 + Sda1/sda1.xml | 20 +++++++++++--- 5 files changed, 50 insertions(+), 26 deletions(-) diff --git a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/DataInsert.java b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/DataInsert.java index 19fa7f979..ac50830cf 100644 --- a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/DataInsert.java +++ b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/DataInsert.java @@ -18,6 +18,7 @@ public class DataInsert { * @throws SQLException */ public DataInsert(final Connection conn) throws SQLException { + conn.setAutoCommit(false); stmt = conn.createStatement(); } @@ -78,8 +79,8 @@ public class DataInsert { * Closing internal Statement instance * @throws SQLException */ - public void close() throws SQLException { - stmt.close(); + public void commit() throws SQLException { + stmt.getConnection().commit(); } } diff --git a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/Xml2Rdbms.java b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/Xml2Rdbms.java index 183507fd5..59cccffb8 100644 --- a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/Xml2Rdbms.java +++ b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/Xml2Rdbms.java @@ -34,18 +34,18 @@ public class Xml2Rdbms { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { - log.info(Messages.getString("Xml2Rdbms.0")); //$NON-NLS-1$ + log.info(Messages.getString("Xml2Rdbms.0")); final SAXParserFactory saxPf = SAXParserFactory.newInstance(); final SAXParser saxParser = saxPf.newSAXParser(); final XMLReader xmlReader = saxParser.getXMLReader(); // Register Driver - final String sqlDriverClassName = Messages.getString("Xml2Rdbms.jdbcDriverName"); //$NON-NLS-1$ + final String sqlDriverClassName = Messages.getString("Xml2Rdbms.jdbcDriverName"); try { Class.forName(sqlDriverClassName); } catch (ClassNotFoundException e) { - Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableRegisterDriverClass") + sqlDriverClassName + Messages.getString("Xml2Rdbms.3"), 1); //$NON-NLS-1$ //$NON-NLS-2$ + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableRegisterDriverClass") + sqlDriverClassName + Messages.getString("Xml2Rdbms.3"), 1); } @@ -53,36 +53,35 @@ public class Xml2Rdbms { // Connection conn = null; - final String jdbcConnectionUrl = Messages.getString("Xml2Rdbms.jdbcUrl"); //$NON-NLS-1$ - final String userName = Messages.getString("Xml2Rdbms.jdbcUser"); //$NON-NLS-1$ + final String jdbcConnectionUrl = Messages.getString("Xml2Rdbms.jdbcUrl"); + final String userName = Messages.getString("Xml2Rdbms.jdbcUser"); try { - conn = DriverManager.getConnection(jdbcConnectionUrl, userName, Messages.getString("Xml2Rdbms.jdbcPasswd")); //$NON-NLS-1$ + conn = DriverManager.getConnection(jdbcConnectionUrl, userName, Messages.getString("Xml2Rdbms.jdbcPasswd")); } catch (SQLException e) { - Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableToConnect") + userName + Messages.getString("Xml2Rdbms.8") + //$NON-NLS-1$ //$NON-NLS-2$ - jdbcConnectionUrl + Messages.getString("Xml2Rdbms.9"), 1); //$NON-NLS-1$ + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableToConnect") + userName + Messages.getString("Xml2Rdbms.8") + + jdbcConnectionUrl + Messages.getString("Xml2Rdbms.9"), 1); } DataInsert dataInsert = null; try { dataInsert = new DataInsert(conn); } catch (SQLException e) { - Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableInitDataInsert"), 1); //$NON-NLS-1$ + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableInitDataInsert"), 1); } - log.info(Messages.getString("Xml2Rdbms.11")); //$NON-NLS-1$ + log.info(Messages.getString("Xml2Rdbms.11")); xmlReader.setContentHandler(new CatalogContentHandler(dataInsert)); xmlReader.setErrorHandler(new SaxErrorHandler(System.err)); - final String xmlDocumentInstanceFilename = Messages.getString("Xml2Rdbms.xmlSourceFileName"); //$NON-NLS-1$ - log.info(Messages.getString("Xml2Rdbms.13") + xmlDocumentInstanceFilename + Messages.getString("Xml2Rdbms.14")); //$NON-NLS-1$ //$NON-NLS-2$ + final String xmlDocumentInstanceFilename = Messages.getString("Xml2Rdbms.xmlSourceFileName"); + log.info(Messages.getString("Xml2Rdbms.13") + xmlDocumentInstanceFilename + Messages.getString("Xml2Rdbms.14")); xmlReader.parse(xmlDocumentInstanceFilename); // Closing try { - dataInsert.close(); // Closing Statement conn.close(); // Closing Connection } catch (SQLException e) { - Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableCloseRdbms"), 1); //$NON-NLS-1$ + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableCloseRdbms"), 1); } } diff --git a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/handler/CatalogContentHandler.java b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/handler/CatalogContentHandler.java index 6e2510265..6f1236a9d 100644 --- a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/handler/CatalogContentHandler.java +++ b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/handler/CatalogContentHandler.java @@ -1,5 +1,6 @@ package de.hdm_stuttgart.mi.sda1.catalog2sql.handler; +import java.sql.SQLException; import java.util.List; import java.util.Vector; @@ -11,6 +12,8 @@ import org.xml.sax.Locator; import org.xml.sax.SAXException; import de.hdm_stuttgart.mi.sda1.catalog2sql.DataInsert; +import de.hdm_stuttgart.mi.sda1.catalog2sql.Helper; +import de.hdm_stuttgart.mi.sda1.catalog2sql.Messages; /** * Turning XML data into SQL INSERT statements @@ -20,7 +23,7 @@ public class CatalogContentHandler implements ContentHandler { private static final Logger log = LogManager.getLogger(CatalogContentHandler.class); Locator locator = null; - final DataInsert sqlFormatter; + final DataInsert sqlInserter; private final List<String> currentDescriptions = new Vector<String>(); @@ -32,7 +35,7 @@ public class CatalogContentHandler implements ContentHandler { * @param sqlFormatter SQL INSERT statement formatter */ public CatalogContentHandler(final DataInsert sqlFormatter) { - this.sqlFormatter = sqlFormatter; + this.sqlInserter = sqlFormatter; } @Override @@ -67,10 +70,10 @@ public class CatalogContentHandler implements ContentHandler { switch(qName) { case "product": if (null == productAgeString) { - sqlFormatter.insertproduct(productId, productName); + sqlInserter.insertproduct(productId, productName); } else { try { - sqlFormatter.insertproduct(productId, productName, Integer.parseInt(productAgeString)); + sqlInserter.insertproduct(productId, productName, Integer.parseInt(productAgeString)); } catch (NumberFormatException ex) { log.error("Property <age> is not of integer value:" + productAgeString); } @@ -92,9 +95,18 @@ public class CatalogContentHandler implements ContentHandler { break; } } + + @Override public void endDocument() throws SAXException { + try { + sqlInserter.commit(); + } catch (SQLException e) { + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableCommitTransaction"), 1); + } + } + private void flushDescriptionEntries() { // Add <description> related INSERTs - sqlFormatter.insertDescription(productId, currentDescriptions); + sqlInserter.insertDescription(productId, currentDescriptions); // Next <product> may be yet to come, so // clear the current set of descriptions. @@ -110,7 +122,6 @@ public class CatalogContentHandler implements ContentHandler { // We don't need these remaining callbacks @Override public void startDocument() throws SAXException {} - @Override public void endDocument() throws SAXException {} @Override public void startPrefixMapping(String prefix, String uri) throws SAXException {} @Override public void endPrefixMapping(String prefix) diff --git a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/messages.properties b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/messages.properties index ef6d55455..1d5308c65 100644 --- a/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/messages.properties +++ b/Sda1/P/catalog2rdbms/src/main/java/de/hdm_stuttgart/mi/sda1/catalog2sql/messages.properties @@ -14,3 +14,4 @@ Xml2Rdbms.jdbcPasswd=XYZ Xml2Rdbms.jdbcUrl=jdbc:mysql://localhost:3306/hdm Xml2Rdbms.jdbcUser=hdmuser Xml2Rdbms.xmlSourceFileName=products.xml +Xml2Rdbms.errMsgUnableCommitTransaction=Unable to commit transaction \ No newline at end of file diff --git a/Sda1/sda1.xml b/Sda1/sda1.xml index a4f6545c0..ca75ad933 100644 --- a/Sda1/sda1.xml +++ b/Sda1/sda1.xml @@ -77,8 +77,8 @@ complete list is available at <uri xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.sda1/apb.html">http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.sda1/apb.html</uri>.</para> - <para>You may also want to use the corresponding PDF version of - the above table within <filename + <para>You may also want/This solut to use the corresponding PDF + version of the above table within <filename xlink:href="http://www.mi.hdm-stuttgart.de/freedocs/topic/de.hdm_stuttgart.mi.sda1/printversion.pdf">printversion.pdf</filename> to keep track of your personal advances by filling in your completion status on individual exercises.</para> @@ -9661,7 +9661,15 @@ public class SimpleInsert { a relational database.</para> <para>Error handling may be implemented by simply issuing a - corresponding message before exiting the application.</para> + corresponding message before exiting the application. In order + to assure data integrity transferring data shall be realized + in a all-or-nothing fashion by grouping all + <code>INSERT</code>s into a single transaction. You may want + to read about <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#setAutoCommit-boolean-">setAutoCommit(boolean + autoCommit)</link> and <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#commit--">commit()</link> + for this purpose.</para> </question> <answer> @@ -9671,7 +9679,11 @@ public class SimpleInsert { <para>This solution requires a <command>mvn</command> <option>install</option> on dependent project - <quote>saxerrorhandler</quote>.</para> + <quote>saxerrorhandler</quote>:</para> + + <annotation role="make"> + <para role="eclipse">P/saxerrorhandler</para> + </annotation> </answer> </qandaentry> </qandadiv> -- GitLab