Code I inherited has many transaction code methods of this form:
public void addCourseToCourses(String values)
{
try
{
conn.setAutoCommit(false);
}
catch (SQLException e)
{
Logger.getLogger(connDb.class.getName()).log(Level.SEVERE, null, e);
return;
}
try
{
stmt.executeUpdate("insert into courses values " + values);
conn.commit();
}
catch (SQLException e)
{
try
{
conn.rollback();
}
catch (SQLException ex)
{
Logger.getLogger(connDb.class.getName()).log(Level.SEVERE,null, ex);
}
}
finally
{
try
{
conn.setAutoCommit(true);
}
catch (SQLException ex)
{
Logger.getLogger(connDb.class.getName()).log(Level.SEVERE,null, ex);
}
}
}
Where the variable part that differs between methods is
stmt.executeUpdate("insert into courses values " + values);
Some times it is several inserts, sometimes it is deletes.
I Miss using Macros coming from C++, but I am sure there is a way not to repeat all this transaction code for each method.
help ?
(conn and stmt are class members of types java.sql.Connection and java.sql.Statement)
Create a method that takes an interface and wraps up the exception handling.
Each interface’s anonymous (or not) implementation contains the SQL call, its parameters, etc.
For example (very roughly):
The
handleSqlis a static import of something resembling:Various hooks can be added as seem reasonable. A generic version would allow various return types, which is likely more appropriate, just depends on what you actually need.
A comment mentions
RunnableandCallable, IMORunnableis specifically for threads (and the base interface isn’t generic).Callableis a better choice, but I’d expect enough other hooks would be added to handle SQL-/JDBC-specific functionality that I’d use something app-specific. YMMV.This pattern has been re-invented all over the place; it may make more sense to take something like Spring JDBC and just use that.