• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解SpringBoot中JdbcTemplate的事务控制

springboot 搞代码 4年前 (2022-01-09) 29次浏览 已收录 0个评论
文章目录[隐藏]

前言

JdbcTemplate是spring-jdbc提供的数据库核心操作类,那对JdbcTemplate进行事务控制呢?

我的环境:spring-boot-2.1.3,druid-1.1.3。

原生Jdbc的事务控制

即,批处理+自动提交的控制方式,

public static void demo(String[] args) throws SQLException, ClassNotFoundException {
    String url = "jdbc:mysql://10.1.4.16:3306/szhtest";
    String username = "ababab";
    String password = "123456";
    String sql1 = "insert xx";
    String sql2 = "insert xx";
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection(url, username, password);
    Statement statement = conn.createStatement();
    // 获取到原本的自动提交状态
    boolean ac = conn.getAutoCommit();
    // 批处理多条sql操作
    statement.addBatch(sql1);
    statement.addBatch(sql2);
    // 关闭自动提交
    conn.setAutoCommit(false);
    try {
        // 提交批处理
        statement.executeBatch();
        // 若批处理无异常,则准备手动commit
        conn.commit();
    } catch (Exception e) {
        e.printStackTrace();
        // 批处理抛异常,则rollback
        try {
            conn.rollback();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    } finally {
        // 恢复到原本的自动提交状态
        conn.setAutoCommit(ac);
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Spring的声明式事务控制

Bean的类或方法上加@Transactional,事务控制粒度较大,只能控制在方法级别,不能控制到代码粒度级别。

尝试JdbcTemplate的事务控制

采取跟原生jdbc事务控制一样的方法试试,在批处理前关闭自动提交,若批处理失败则回滚的思路。

@RequestMapping("/druidData1")
public String druidData1() throws SQLException {
    String sql1 = "INSERT INTO user_tmp(`id`, `username`) VALUES(22, 222)";
    // id=1的主键冲突<p>本文来源gao!%daima.com搞$代*!码9网(</p>插入失败
    String sql2 = "INSERT INTO user_tmp(`id`, `username`) VALUES(1, 111)";
    Connection conn = jdbcTemplate.getDataSource().getConnection();
    LOG.info("1:{}", conn);
    boolean ac = conn.getAutoCommit();
    conn.setAutoCommit(false);
    try {
        int[] rs2 = jdbcTemplate.batchUpdate(new String[]{sql1, sql2});
        conn.commit();
    } catch (Throwable e) {
        LOG.error("Error occured, cause by: {}", e.getMessage());
        conn.rollback();
    } finally {
        conn.setAutoCommit(ac);
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                LOG.error("Error occurred while closing connectin, cause by: {}", e.getMessage());
            }
        }
    }
    return "test";
}

期望结果:id=1的因为主键冲突,所以id=22的也要回滚。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解SpringBoot中JdbcTemplate的事务控制
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址