How do I get the connection inside of a Spring transaction?

Viewed 19048

Imagine this code:

foo() {
     Connection conn = ...;
}

foo() has been called from a method that has the annotation @Transactional. How do I get the current JDBC connection? Note that foo() is in a bean (so it can have @Autowired fields) but foo() can't have parameters (so I can't pass the connection in from somewhere).

[EDIT] I'm using jOOQ which needs either a data source or a connection. My problem: I don't know which transaction manager is configured. It could be anything; Java EE, DataSource based, something which gets the data source via JNDI. My code isn't an application, it's a library. I need to swallow what others put on my plate. Along the same lines, I can't request a Hibernate session factory because the application using me might not use Hibernate.

But I know that other code, like the Spring Hibernate integration, somehow can get the current connection from the transaction manager. I mean, Hibernate doesn't support Spring's transaction manager, so the glue code must adapt the Spring API to what Hibernate expects. I need to do the same thing but I couldn't figure out how it works.

[EDIT2] I know that there is an active transaction (i.e. Spring has a Connection instance somewhere or at least a transaction manager which can create one) but my method isn't @Transactional. I need to call a constructor which takes java.sql.Connection as parameter. What should I do?

6 Answers

3 another ways:

@Component
public class MyServiceNonTransactional {

    @Autowired
    private TransactionTemplate transactionTemplate;
    
    @Autowired
    private DataSource dataSource;
    
    public void doStuff() {
        transactionTemplate.executeWithoutResult(status -> {
            Connection connection = DataSourceUtils.getConnection(dataSource);
            // here we go...
        });
    }

}

@Service
public class MyServiceTransactional {

    @Autowired
    private DataSource dataSource;
    
    @Transactional
    public void doStuff() {
        Connection connection = DataSourceUtils.getConnection(dataSource);
        // here we go...
    }

}

@Service
public class MyServiceViaJdbc {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void doStuff() {
        jdbcTemplate.execute((ConnectionCallback<Void>) conn -> {
            // "conn" here we go!
            return null;
        });
    }
        
}
Related