• 在使用Transaction事务的方法中,catch到异常并手动进行事务回滚。


    今天在做使用Quartz进行定时更新数据操作时,发现在加了事务的方法在try{}catch{}捕获异常的时候,事务无法进行回滚

    这个是添加事务的接口:

      /**
         * 更新实时数据
         */
        @Transactional
        public Map<String,Object> batchAddHik();

    实现类捕获异常代码块:

    /**
         * 定时批量更新数据
         */
        @Override
        public Map<String,Object> batchAddHik() {
            //..
            Map<String,Object> map = new HashMap<String, Object>(); 
         final List<Object[]> insertParams = new ArrayList<Object[]>();
            for (ClInout clInout : clInouts) {
                String plateNo = clInout.getPlateNo();
                String crossTime = clInout.getCrossTime();
                Integer releaseMode = clInout.getReleaseMode();
                Integer vehicleSize = clInout.getVehicleSize();
                Integer carOut = clInout.getCarOut();
                String platePicUrl = clInout.getPlatePicUrl() == null ? "" : clInout.getPlatePicUrl();
                String vehiclePicUrl = clInout.getVehiclePicUrl() == null ? "" : clInout.getVehiclePicUrl();
                String facePicUrl = clInout.getFacePicUrl() == null ? "" : clInout.getFacePicUrl();
                String hikRecordUuid = clInout.getHikRecordUuid();
    
                insertParams.add(new Object[] {plateNo,crossTime,releaseMode,vehicleSize,carOut,platePicUrl,vehiclePicUrl,facePicUrl,hikRecordUuid});
            }
    
            String sql = "INSERT INTO cl_inout (plate_no, cross_time, release_mode, vehicle_size, car_out, plate_pic_url, vehicle_pic_url, face_pic_url, hik_record_uuid)"
                    + "VALUES (?,?,?,?,?,?,?,?,?)";
    
            if (clInouts.size() > 0) {
    
                try {
                    num = this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
                        @Override
                        public void setValues(PreparedStatement ps, int i) throws SQLException { 
                            Object[] args = insertParams.get(i);
                            ps.setString(1, (String) args[0]);
                            ps.setString(2, (String) args[1]);
                            ps.setInt(3, (Integer) args[2]);
                            ps.setInt(4, (Integer) args[3]);
                            ps.setInt(5, (Integer) args[4]);
                            ps.setString(6, (String) args[5]);
                            ps.setString(7, (String) args[6]);
                            ps.setString(8, (String) args[7]);
                            ps.setString(9, (String) args[8]);
                        }
    
                        @Override
                        public int getBatchSize() {
                            return insertParams.size();
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    String message = e.getMessage();
                    map.put("exception", message);
                    map.put("number", 0);
    
                }
    
            }
        //..
    }   

    此时,在batchUpdate过程若catch到异常,事务将无法回滚,程序依然会将部分插入到数据库中。

    解决办法:

    spring在捕获RuntimeException异常后,才会进行事务回滚。

    故,在catch代码块中,添加:

    } catch (Exception e) {
                    e.printStackTrace();
                    String message = e.getMessage();
                    map.put("exception", message);
                    map.put("number", 0);
                    // 手动设置当前事务回滚
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    // 或者手动抛出runTimeException
    //                throw new RuntimeException();
                }

    这样,便能让事务回滚了又捕获到异常了。

  • 相关阅读:
    linux 下 设置 MySQL8 表名大小写不敏感方法,解决设置后无法启动 MySQL 服务的问题
    JavaWeb入门_模仿天猫整站Tmall_JavaEE实践项目
    flowable工作流笔记
    bladex前端反向代理(解决跨域)
    Long类型传值前端精度丢失
    blade普通字典关联
    一些东西
    java面试题经典解读
    html元素定位原理
    行转换为列
  • 原文地址:https://www.cnblogs.com/libera11/p/8054072.html
Copyright © 2020-2023  润新知