混合JdbcTemplate和原始JDBC

时间:2015-05-31 15:07:41

标签: spring spring-boot spring-data spring-jdbc

我正在经历一些我无法轻易解释的奇怪行为。以下代码运行正常:

    try (Connection connection = dataSource.getConnection();
         Statement statement = connection.createStatement()) {
        statement.executeUpdate("DELETE FROM product");

    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }

    try (Connection connection = dataSource.getConnection();
         Statement statement = connection.createStatement()) {
         statement.executeUpdate("INSERT INTO product ...");

    } catch (SQLException ex) {
        throw new RuntimeException(ex);
    }

但是这段代码导致死锁:

    jdbcTemplate.update("DELETE FROM product");

    try (Connection connection = dataSource.getConnection();
         Statement statement = connection.createStatement()) {
         statement.executeUpdate("INSERT INTO product ...");

    } catch (SQLException ex) {
        throw new RuntimeException(ex);
    }

例外是

java.sql.SQLException:超出锁定等待超时;尝试重新启动交易

jdbcTemplate和dataSource都是由Spring启动和自动装配的

创建的
@Autowired
private DataSource dataSource;

@Autowired
private JdbcTemplate jdbcTemplate;

语句构成服务中方法的一部分(使用@Transactional注释)

有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

如果您想使用自己的JDBC代码,这些代码与Spring的事务管理所管理的连接很好,您应该使用DataSourceUtils来获取连接 - 请参阅http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/DataSourceUtils.html#getConnection-javax.sql.DataSource-

在您的示例中,根据事务配置,可能尚未提交使用JdbcTemplate的第一个语句,因此它将阻止来自不同连接的下一个JDBC语句。使用DataSourceUtils,两个语句都将使用相同的连接。