Spring嵌套事务​​不能与jOOQ一起使用

时间:2015-10-01 17:10:01

标签: java sql spring jooq

我希望使用Spring @Transactional来管理我的交易,并通过关注this example来支持嵌套交易。

我的问题是,如果我致电UserService.addAdmin()SpringTransactionProvider.begin()SpringTransactionProvider.commit()由于某种原因没有被调用,这表明它的工作方式与我正在进行的方式相同。< / p>

我正在实施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没有被利用?

1 个答案:

答案 0 :(得分:1)

jOOQ&#39; s TransactionProvider提供了明确jOOQ transaction 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的声明式TransactionProvider API,则不会涉及@Transaction。换句话说,你不需要它。