[英]Spring nested transactions not working with jOOQ
我想通过Spring @Transactional
管理我的事务,并通过执行以下示例来支持嵌套事务。
我的问题是,如果我致电UserService.addAdmin()
, SpringTransactionProvider.begin()
由于某种原因未调用SpringTransactionProvider.begin()
和SpringTransactionProvider.commit()
,这表明它无法按我的方式工作。
我正在实施我的服务 :
/*
*
*/
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();
}
}
以及定义我的配置文件 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>
基本上是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);
}
}
我本来希望看到
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 ####
但我只会
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!
为什么SpringTrancationProvider
没有得到利用?
jOOQ的TransactionProvider
为显式jOOQ事务API提供了一个实现,将其连接到您似乎没有使用的Spring。 使用显式jOOQ事务API的示例addAdmin()
方法将是以下示例:
// 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();
});
}
如果您使用Spring的声明性@Transaction
API,则不涉及TransactionProvider
。 换句话说,您不需要它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.