繁体   English   中英

Spring嵌套事务​​不适用于jOOQ

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM