如何在Spring中为两个查询使用相同的连接?

我在基于Spring JdbcTemplate的dao中有以下代码 –

getJdbcTemplate().update("Record Insert Query..."); int recordId = getJdbcTemplate().queryForInt("SELECT last_insert_id()"); 

问题是我有时使用连接池中的不同连接来执行update和queryForInt查询。

这导致返回错误的recordId,因为应该从发出插入查询的同一连接调用MySql last_insert_id()。

我考虑过SingleConnectionDataSource但不想使用它,因为它会降低应用程序性能。 我只想要这两个查询的单一连接。 并非所有服务的所有请求。

所以我有两个问题:

  1. 我可以管理模板类使用的连接吗?
  2. JdbcTemplate是否执行自动事务管理? 如果我手动将事务应用于我的Dao方法,是否意味着每个查询将创建两个事务?

希望你们能够对这个话题有所了解。

更新 – 我尝试了nwinkler的方法并将我的服务层包装在一个事务中。 我很惊讶地发现在一段时间之后会再次弹出相同的错误。 深入研究Spring源代码我发现了这个 –

 public  T execute(PreparedStatementCreator psc, PreparedStatementCallback action) throws DataAccessException { //Lots of code Connection con = DataSourceUtils.getConnection(getDataSource()); //Lots of code } 

因此,与我的想法相反,每个事务不一定有一个数据库连接,但每个查询执行一个连接。 这让我回到了我的问题。 我想从同一个连接执行两个查询。 🙁

更新

                            

确保您的DAO包含在事务中(例如,使用Spring的Interceptor for Transactions)。 然后,两个呼叫将使用相同的连接。

更好的方法是在服务层将事务提高一级。

文档: http : //static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

更新:如果您查看更新中引用的DataSourceUtils.getConnection()方法的JavaDoc,您将看到它获得与当前线程关联的连接:

知道绑定到当前线程的相应Connection,例如使用{@link DataSourceTransactionManager}时。 如果事务同步处于活动状态,则会将Connection绑定到线程,例如,在{@link org.springframework.transaction.jta.JtaTransactionManager JTA}事务中运行时。

根据这个,它应该像你设置它一样工作。 我已经使用过这种模式很多次了,从来没有遇到像你描述的任何问题……

还请看一下这个post,有人在那里处理类似的问题: 创建了Spring Jdbc声明式事务,但没有做任何事情

这是我的方法:

 namedJdbcTemplate.execute(savedQuery, map, new PreparedStatementCallback() { @Override public Object doInPreparedStatement(PreparedStatement paramPreparedStatement) throws SQLException, DataAccessException { paramPreparedStatement.execute("SET @userLogin = 'blabla123'"); paramPreparedStatement.executeUpdate(); return null; } });