【发布时间】:2015-12-29 20:02:05
【问题描述】:
我想使用 Spring @Transactional 管理我的事务,并通过关注 this example 来支持嵌套事务。
我的问题是,如果我打电话给UserService.addAdmin(),那么SpringTransactionProvider.begin() 和SpringTransactionProvider.commit() 由于某种原因没有被调用,这表明它没有按照我的方式工作..
我正在实施我的service:
/*
*
*/
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();
}
}
以及定义我的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>
基本上是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 没有被使用?
【问题讨论】: