Reputation: 25397
I want to manage my transactions with Spring @Transactional
and support nested transaction by following this example in order to do so.
My problem is if I call UserService.addAdmin()
that SpringTransactionProvider.begin()
and SpringTransactionProvider.commit()
are not getting called for some reason which indicates that it is not working the way I'm doing it ..
I'm having my service implemented:
/*
*
*/
public class UserService {
private final static Logger LOGGER = Logger.getLogger(UserService.class.getName());
private AdminRepository adminRepository;
public UserService(DSLContext ctx) {
this.adminRepository = new AdminRepository(ctx);
}
@Transactional
public void addAdmin(String userId) {
DSLContext ctx = adminRepository.getCtx();
ctx.insertInto(Admin.ADMIN)
.set(Admin.ADMIN.USER_NAME, userId)
.execute();
}
}
As well as defined my configuration file servlet-context.xml
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/mz_db" />
<property name="username" value="postgres" />
<property name="password" value="huehuehue" />
</bean>
<!-- Configure Spring's transaction manager to use a DataSource -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- Configure jOOQ's TransactionProvider as a proxy to Spring's transaction manager -->
<bean id="transactionProvider"
class="com.mz.server.web.SpringTransactionProvider">
</bean>
<!-- Configure jOOQ's ConnectionProvider to use Spring's TransactionAwareDataSourceProxy,
which can dynamically discover the transaction context -->
<bean id="transactionAwareDataSource"
class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="dataSource" />
</bean>
<bean class="org.jooq.impl.DataSourceConnectionProvider" name="connectionProvider">
<constructor-arg ref="transactionAwareDataSource" />
</bean>
<!-- Configure the DSL object, optionally overriding jOOQ Exceptions with Spring Exceptions -->
<bean id="dsl" class="org.jooq.impl.DefaultDSLContext">
<constructor-arg ref="config" />
</bean>
<!-- Invoking an internal, package-private constructor for the example
Implement your own Configuration for more reliable behaviour -->
<bean class="org.jooq.impl.DefaultConfiguration" name="config">
<property name="SQLDialect"><value type="org.jooq.SQLDialect">POSTGRES_9_4</value></property>
<property name="connectionProvider" ref="connectionProvider" />
<property name="transactionProvider" ref="transactionProvider" />
</bean>
<!-- BEGIN Services -->
<bean id="userService" class="com.mz.server.web.service.UserService">
<constructor-arg>
<ref bean="dsl" />
</constructor-arg>
</bean>
and basically a copy of SpringTransactionProvider
:
public class SpringTransactionProvider implements TransactionProvider {
private final static Logger LOGGER = Logger.getLogger(SpringTransactionProvider.class);
@Autowired
DataSourceTransactionManager txMgr;
public SpringTransactionProvider() {
LOGGER.info("Ctor()");
}
@Override
public void begin(TransactionContext ctx) {
LOGGER.info("##### begin #####");
TransactionStatus tx = txMgr.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NESTED));
ctx.transaction(new SpringTransaction(tx));
}
@Override
public void commit(TransactionContext ctx) {
LOGGER.info("##### commit #####");
txMgr.commit(((SpringTransaction) ctx.transaction()).tx);
}
@Override
public void rollback(TransactionContext ctx) {
LOGGER.info("##### rollback #####");
txMgr.rollback(((SpringTransaction) ctx.transaction()).tx);
}
}
I would have expected to see
INFO com.mz.server.web.SpringTransactionProvider - Ctor()
DEBUG com.mz.server.web.servlet.UserServletImpl - Login request by userId: username
INFO com.mz.server.web.SpringTransactionProvider - #### begin ####
INFO com.mz.server.web.service.UserService - Yay!
INFO com.mz.server.web.SpringTransactionProvider - #### commit ####
but I'm only getting
INFO com.mz.server.web.SpringTransactionProvider - Ctor()
DEBUG com.mz.server.web.servlet.UserServletImpl - Login request by userId: username
INFO com.mz.server.web.service.UserService - Yay!
Why does the SpringTrancationProvider
not getting utilized?
Upvotes: 3
Views: 2245
Reputation: 220952
jOOQ's TransactionProvider
provides an implementation for the explicit jOOQ transaction API, wiring it to Spring, which you don't seem to be using. An example addAdmin()
method that uses the explicit jOOQ transaction API would be this one:
// no @Transactional - no need for declarative transaction management
public void addAdmin(String userId) {
adminRepository.getCtx().transaction(configuration -> {
DSL.using(configuration)
.insertInto(Admin.ADMIN)
.set(Admin.ADMIN.USER_NAME, userId)
.execute();
});
}
The TransactionProvider
is not involved if you use Spring's declarative @Transaction
API. In other words, you don't need it.
Upvotes: 1