title: Force Spring/JPA/Hibernate/JDBC to retry a failed beginTransaction?
body: <p>Sometimes a db transaction can't begin because of a simple SocketException when trying to reach MySQL. In the current codebase, all SQL or JPQL code resides in classes with the @Transactional annotation  (org.springframework.transaction.annotation). A transaction is created for me for each method call to an annotated class. This makes it difficult to write code that can be reused across all db calls.</p>
  
  <p>One solution would be to put the db code within a loop: It will retry the transaction a few times. This works but I'd prefer not to sprinkle my code full of loops (one for each db call).</p>
  
  <p>Is their a way to make either one of the following frameworks retry a failed beginTransaction automatically?: Spring, JPA, Hibernate, c3p0, MySQL JDBC driver</p>
  
  <p>For reference, here is a piece of the log:</p>
  
  <pre><code>java.net.SocketException
  MESSAGE: Connection reset
  
  STACKTRACE:
  java.net.SocketException: Connection reset
          at java.net.SocketInputStream.read(SocketInputStream.java:168)
          at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
          at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
          at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
          at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1910)
          at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
          at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
          at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
          at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
          at com.mysql.jdbc.Connection.execSQL(Connection.java:3170)
          at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5273)
          at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881)
          at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:91)
          at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1353)
          at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:38)
          at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:70)
          at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:52)
          at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:330)
          at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:374)
          at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
          at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
  </code></pre>
  
  <p>PS. I hate automagic frameworks that supposedly solve all problems. It wasn't my decision to make in this project.</p>