Hello, I'm really sorry to hear that a few people have been having issues with jOOQ 3.x and transactions, recently. We take these reports seriously and we'll push creating an integration-tested jOOQ/Spring tutorial next week. Thanks to the help from Brad Cox: https://groups.google.com/forum/#!topic/jooq-user/b9beZNsnbEA
... and from Petri Kainulainen, who will write a jOOQ / Spring blog post in the next few days: https://twitter.com/petrikainulaine/status/418848654498078720 ... I'm sure we'll be able to tackle this issue together. Until then, I need you to bear with me, or maybe, help debug through your issue. There might be a bug that is not yet known to us. Lukas 2014/1/2 Stargate <[email protected]> > Hi, > > no that is not the issue in 2.6.1 this works.. But i have tried to put the > @Transcational over the method and this has no effect. > I hope someone can help me, it is very frustrating that > TransactionHandling is so difficult with jooq. > > > Am Donnerstag, 2. Januar 2014 18:08:20 UTC+1 schrieb Lukas Eder: >> >> Hi, >> >> I'm not really a Spring TX authority, so I'm just guessing from looking >> at your code... >> One thing that seems fishy to me is the fact that you put @Transactional >> on the class, not on the relevant method. Is that the issue here? >> >> Cheers >> Lukas >> >> >> 2014/1/2 Stargate <[email protected]> >> >>> Hi, >>> >>> hm i can try to build a project, but this would take some time.. >>> >>> or will this implementation http://www.jooq.org/doc/3.2/ >>> manual/getting-started/tutorials/jooq-with-spring/ work with the >>> @Transcational Annotation from Spring ? >>> >>> >>> The problem he descripted in his blog http://blog.uws.ie/2013/04/ >>> using-jooq-with-spring-transactions/ ist that he gets different >>> connections.. i also use a pooled connection >>> the 2.6.1 SpringListener looks like this: >>> >>> >>> >>>> import java.sql.Connection; >>>> import java.sql.SQLException; >>>> import java.sql.Statement; >>>> >>>> import javax.sql.DataSource; >>>> >>>> import org.jooq.ExecuteContext; >>>> import org.jooq.impl.DefaultExecuteListener; >>>> import org.springframework.jdbc.datasource.DataSourceUtils; >>>> import org.springframework.jdbc.support.JdbcUtils; >>>> import org.springframework.jdbc.support. >>>> SQLErrorCodeSQLExceptionTranslator; >>>> import org.springframework.jdbc.support.SQLExceptionTranslator; >>>> import org.springframework.jdbc.support. >>>> SQLStateSQLExceptionTranslator; >>>> >>>> @SuppressWarnings("UnusedDeclaration") >>>> >>>> public class SpringExceptionTranslationExecuteListener extends >>>> DefaultExecuteListener { >>>> >>>> @Override >>>> public void start(ExecuteContext ctx) { >>>> DataSource dataSource = ctx.getDataSource(); >>>> Connection c = DataSourceUtils.getConnection(dataSource); >>>> ctx.setConnection(c); >>>> } >>>> >>>> @Override >>>> public void exception(ExecuteContext ctx) { >>>> SQLException ex = ctx.sqlException(); >>>> Statement stmt = ctx.statement(); >>>> Connection con = ctx.getConnection(); >>>> DataSource dataSource = ctx.getDataSource(); >>>> JdbcUtils.closeStatement(stmt); >>>> ctx.exception(getExceptionTranslator( >>>> dataSource).translate("jOOQ", >>>> ctx.sql(), ex)); >>>> } >>>> >>>> /** >>>> * Return the exception translator for this instance. >>>> * <p> >>>> * Creates a default {@link SQLErrorCodeSQLExceptionTranslator} >>>> for the >>>> * specified DataSource if none set, or a >>>> * {@link SQLStateSQLExceptionTranslator} in case of no >>>> DataSource. >>>> */ >>>> public synchronized SQLExceptionTranslator >>>> getExceptionTranslator( >>>> DataSource dataSource) { >>>> final SQLExceptionTranslator exceptionTranslator; >>>> if (dataSource != null) { >>>> exceptionTranslator = new SQLErrorCodeSQLExceptionTransl >>>> ator( >>>> dataSource); >>>> } else { >>>> exceptionTranslator = new SQLStateSQLExceptionTranslator >>>> (); >>>> } >>>> return exceptionTranslator; >>>> } >>>> } >>>> >>> >>> >>> And my new one with 3.2.2 looks like this: >>> >>> import java.sql.Connection; >>>> import java.sql.SQLException; >>>> import java.sql.Statement; >>>> >>>> import javax.sql.DataSource; >>>> >>>> import org.jooq.ConnectionProvider; >>>> import org.jooq.ExecuteContext; >>>> import org.jooq.impl.DataSourceConnectionProvider; >>>> import org.jooq.impl.DefaultExecuteListener; >>>> import org.springframework.jdbc.datasource.DataSourceUtils; >>>> import org.springframework.jdbc.support.JdbcUtils; >>>> import org.springframework.jdbc.support. >>>> SQLErrorCodeSQLExceptionTranslator; >>>> import org.springframework.jdbc.support.SQLExceptionTranslator; >>>> import org.springframework.jdbc.support. >>>> SQLStateSQLExceptionTranslator; >>>> >>>> @SuppressWarnings("UnusedDeclaration") >>>> >>>> public class SpringExceptionTranslationExecuteListener extends >>>> DefaultExecuteListener { >>>> >>>> >>>> DataSource dataSource2=null; >>>> Connection con=null; >>>> >>>> >>>> >>>> @Override >>>> public void start(ExecuteContext ctx) { >>>> >>>> DataSourceSingleton dataSourceSingleton = >>>> DataSourceSingleton.getReference(); >>>> >>>> try { >>>> dataSource2 = dataSourceSingleton.getDataSource(); >>>> } catch (Exception e) { >>>> e.printStackTrace(); >>>> } >>>> >>>> >>>> DataSourceConnectionProvider dataSourceConnectionProvider=new >>>> DataSourceConnectionProvider(dataSource2); >>>> ctx.connectionProvider(dataSourceConnectionProvider); >>>> >>>> >>>> } >>>> >>>> @Override >>>> public void exception(ExecuteContext ctx) { >>>> SQLException ex = ctx.sqlException(); >>>> Statement stmt = ctx.statement(); >>>> >>>> Connection con = ctx.connection(); >>>> >>>> JdbcUtils.closeStatement(stmt); >>>> >>>> ctx.exception(getExceptionTranslator( >>>> dataSource2).translate("jOOQ",ctx.sql(), ex)); >>>> >>>> } >>>> >>>> /** >>>> * Return the exception translator for this instance. >>>> * <p> >>>> * Creates a default {@link SQLErrorCodeSQLExceptionTranslator} >>>> for the >>>> * specified DataSource if none set, or a >>>> * {@link SQLStateSQLExceptionTranslator} in case of no >>>> DataSource. >>>> */ >>>> public synchronized SQLExceptionTranslator >>>> getExceptionTranslator( >>>> DataSource dataSource) { >>>> final SQLExceptionTranslator exceptionTranslator; >>>> if (dataSource != null) { >>>> exceptionTranslator = new SQLErrorCodeSQLExceptionTransl >>>> ator( >>>> dataSource); >>>> } else { >>>> exceptionTranslator = new SQLStateSQLExceptionTranslator >>>> (); >>>> } >>>> return exceptionTranslator; >>>> } >>>> } >>>> >>> >>> and then the following class is called, i have bind the @Transcational >>> Annotation from Spring via Google Guice to the " >>> TransactionalMethodInterceptor" >>> >>> class TransactionalMethodInterceptor implements MethodInterceptor { >>>> >>>> @Inject >>>> private DataSourceTransactionManager transactionManager; >>>> >>>> >>>> @Override >>>> public Object invoke(final MethodInvocation invocation) throws >>>> Throwable { >>>> DefaultTransactionDefinition transactionDefinition = new >>>> DefaultTransactionDefinition(); >>>> TransactionStatus transaction = transactionManager >>>> .getTransaction(transactionDefinition); >>>> try { >>>> Object result = invocation.proceed(); >>>> try { >>>> transactionManager.commit(transaction); >>>> } catch (UnexpectedRollbackException e) { >>>> LoggerFactory.getLogger(getClass()).error( >>>> "commit failed - ignoring! : " + >>>> e.getMessage()); >>>> >>>> } >>>> return result; >>>> } catch (Exception e) { >>>> >>>> transactionManager.rollback(transaction); >>>> >>>> throw e; >>>> } >>>> } >>>> >>> >>> my programm reaches this class but the " >>> transactionManager.rollback(transaction);" >>> has no effect >>> >>> A example class that uses Transaction-Handling looks like this: >>> >>> @Transactional >>>> public class test(){ >>>> >>>> public DSLContext createFactory() { >>>> >>>> DataSourceConnectionProvider dataSourceProvider=new >>>> DataSourceConnectionProvider(dataSource); >>>> >>>> >>>> Configuration configuration = new DefaultConfiguration().set( >>>> dataSourceProvider).set(SQLDialect.POSTGRES); >>>> >>>> configuration.set(new DefaultExecuteListenerProvider(new >>>> SpringExceptionTranslationExecuteListener())); >>>> >>>> DSLContext create = DSL.using(configuration); >>>> >>>> return create; >>>> >>>> } >>>> >>>> public Integer addAccount(String email, String password,String >>>> telephone) { >>>> >>>> AccountsRecord accountsRecord = createFactory().insertInto( >>>> ACCOUNTS) >>>> .set(ACCOUNTS.EMAIL, email) >>>> .returning(ACCOUNTS.ACCOUNT_ID) >>>> .fetchOne(); >>>> >>>> Integer createdAccountId = accountsRecord.getAccountId(); >>>> >>>> createFactory().insertInto(AUTH).set(AUTH.PASSWORD, >>>> password).execute(); >>>> >>>> PersonalDataRecord personalDataRecord = >>>> createFactory().insertInto(PERSONAL_DATA) >>>> >>>> .set(PERSONAL_DATA.PHONE, telephone) >>>> >>>> .returning(PERSONAL_DATA.PERSONAL_DATA_ID).fetchOne(); >>>> >>>> >>>> return createdAccountId; >>>> } >>>> >>>> >>>> } >>>> >>> >>> >>> in the addAccount Method are 2 insertInto Operations.. the password >>> field in the second insert must have a value! if i call the addAccount() >>> Method with the following parameters addAccount([email protected],null, >>> 1234) it should do a rollback because the password field is null.. But this >>> does not work >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "jOOQ User Group" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >> >> -- > You received this message because you are subscribed to the Google Groups > "jOOQ User Group" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/groups/opt_out. > -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
