zoukankan      html  css  js  c++  java
  • JAVA数据库操作回滚小结

    一:总结的原因

      在最近的工作中,遇到了一个一对多关系多表数据传输,传送成功状态绑定在主数据表上,因为代码不健壮问题造成了主表传送状态更新失败,而子表数据就被重复插入。又由于数据传输频率很高,我们的测试环境就像被官方病毒攻击,疯狂插入了几十个G的数据……

    二:解决步骤

      1.提高代码健壮性,先进行主表状态能否成功更新判断,再插入子表数据,最后再更新主表状态。

      2.进一步提高容错率:将这些存在关系的表的更新集成到一个事物,全部更新都正常执行后,再提交事务。

    三:技术实现

    public void doManipulateData(){
        Connection connection = getConnection();//获取当前环境的连接
        try {
            connection.setAutoCommit(false);//设置不能自动提交
            //1.执行普通的增删改查语句
            doADUS(connection);
            //2.执行存储过程
            doStoredPro(connection);
            connection.commit(); //手动提交
            connection.setAutoCommit(true);//设置可以自动提交
        } catch (SQLException e) {
            try {
                connection.rollback(); //回滚此次链接的所有操作
                connection.setAutoCommit(true); //设置可以自动提交
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            connection.close();//关闭连接
        }
    }
    
    /*
     * 执行普通的增删改查语句
     */
    public void doADUS(Connection connection) throws Exception{
        String sql = "...";
        PreparedStatement ps = null;
        try {
            ps = connection.prepareStatement(sql);
            ps.setString(1, appId);  //ps.setBinaryStream(2, arg1, arg2)
            ps.executeUpdate();
        } catch (SQLException e) {
            throw e;
        } finally {
            ps.close();
        }
    }
    
    /*
     * 执行存储过程
     */
    public void doStoredPro(Connection connection) throws Exception{
        CallableStatement cs = null;
        try {
            cs = connection.prepareCall("{call 过程名称(?,?)}");
            cs.setString(1, "");
            cs.registerOutParameter(2, Types.INTEGER);//存储过程执行返回数据
            cs.execute();
            if (cs.getInt(2) != 0) {
                throw new Exception("存储过程执行失败!");
            }
        } catch (Exception e) {
            throw e;
        } finally {
            ps.close();
        }
    }

     四:注意事项

      1.java.sql.PreparedStatement.setBinaryStream(int parameterIndex, InputStream x, long length) 方法,jdbc并没有提供相应的接口,运行时会报错。需要使用 java.sql.PreparedStatement.setBinaryStream(int parameterIndex, InputStream x, int length)

      2.PreparedStatement 建立的sql对象只编译一次,可使用占位符安全的插入。Statement每次执行sql时都会重新编译一次sql,不能使用占位符

  • 相关阅读:
    Bruce Eckel:编程生涯(转载)
    NSScanner用法详解
    如何为github上的项目添加gif效果图
    iOS-网址集
    支持后台播放音频
    iOS:UITableView 方法 属性
    Quartz2D简介及基本线条绘制
    遍历输出所有子视图(View)
    UIView常用属性与方法/UIKit继承结构
    netty02(接受消息以后进行返回)
  • 原文地址:https://www.cnblogs.com/ttjsndx/p/8687417.html
Copyright © 2011-2022 走看看