2015-10-01 2 views
1

Я хочу управлять своими транзакциями с помощью Spring @Transactional и поддерживать вложенную транзакцию, следуя this example, чтобы сделать это.Весенние вложенные транзакции, не работающие с jOOQ

Моя проблема в том, если я называю 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сервлет-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

jOOQ's TransactionProvider обеспечивает реализацию для явного jOOQ transaction API, проводя его до весны, которую вы, кажется, не используете. Пример addAdmin() метод, который использует явный jOOQ транзакции API будет этот:

// 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(); 
    }); 
} 

TransactionProvider не участвует, если вы используете декларативную @Transaction API Spring в. Другими словами, вам это не нужно.

+0

Ну ладно, я вижу! Причина, по которой я хотел использовать '@ Transactional', - это, например, в Hibernate с использованием Spring у вас нет сеанса без него. Отсутствие сеанса вызовет исключение. Если я выполняю инструкцию 'INSERT' в jOOQ ** без **' @ Transactional' и выдаю исключение, запись сохраняется (нет отката). Но ** с ** '@ Transactional' выполняется откат. Я не совсем понимаю, почему это так. – displayname

+0

Итак, главный вопрос: могу ли я использовать декларативные аннотации Springs с jOOQ и иметь вложенные транзакции, как я это делаю? Я бы предпочел использовать декларативные транзакции с использованием 'DSLContext.transaction()', чтобы иметь внутренние точки сохранения и откаты, если это возможно. – displayname

+0

Да, вы можете использовать декларативные транзакции Spring без каких-либо проблем. jOOQ - это просто безопасный тип JDBC, поэтому, где бы вы не писали заявление JDBC, вы можете написать инструкцию jOOQ. Ничто в jOOQ не мешает этому. Просто поставьте jOOQ с любым «DataSource» из Spring, и вы настроены. Я подозреваю, что есть просто некоторая путаница вокруг того, что точка jOOQ 'TransactionProvider' ... –

Смежные вопросы