【问题标题】:Getting duplicate key exception while doing JDBC transaction执行 JDBC 事务时出现重复键异常
【发布时间】:2019-05-16 22:27:42
【问题描述】:

我正在尝试使用 JDBC 事务添加名称及其薪水。 问题是这会引发关于重复键的异常。

这是我第一次在工资列中放入一些无效数据,之后一切都正确。它显示指定 id 的重复键异常 但指定 id 尚未存储,甚至第一次尝试时也没有存储。 第一个无效的事务被回滚,但在下次存储时显示重复键异常。

下面是我的代码:-

  public boolean addDesignation(ObservableList nodeList) throws SQLException {
        Connection demo = getConnection();
        demo.setAutoCommit(false);
        Savepoint savePoint = demo.setSavepoint("savePoint");
        try {
        PreparedStatement addDesig =  demo.prepareStatement(
                "INSERT INTO `designation`(`desig_id`,`dept_id`,`desig_name`,`desig_desc`) VALUES (?,?,?,?)");
        PreparedStatement addSal =  demo.prepareStatement("INSERT INTO `salary` "
                + "(`desig_id`, `basic`, `house_rent`, `conveyance`, `medical`, `dearness`,`others_allowances`,"
                + " `income_tax`, `pro_tax`, `emp_state_insu`, `absence_fine`, `others_deductions`, `month`)"
                + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");

        addDesig.setString(1 , nodeList.get(0).toString());
        addDesig.setString(2,  nodeList.get(1).toString());
        addDesig.setString(3, nodeList.get(2).toString());
        addDesig.setString(4,  nodeList.get(3).toString());
        addDesig.executeUpdate();

        addSal.setString(1, nodeList.get(0).toString());
        addSal.setInt(2, Integer.parseInt(nodeList.get(4).toString()));
        addSal.setInt(3, Integer.parseInt(nodeList.get(5).toString()));
        addSal.setInt(4, Integer.parseInt(nodeList.get(6).toString()));
        addSal.setInt(5, Integer.parseInt(nodeList.get(7).toString()));
        addSal.setInt(6,Integer.parseInt(nodeList.get(8).toString()));
        addSal.setInt(7,Integer.parseInt(nodeList.get(9).toString()));
        addSal.setInt(8, Integer.parseInt(nodeList.get(10).toString()));
        addSal.setInt(9, Integer.parseInt(nodeList.get(11).toString()));
        addSal.setInt(10, Integer.parseInt(nodeList.get(12).toString()));
        addSal.setInt(11, Integer.parseInt(nodeList.get(13).toString()));
        addSal.setInt(12, Integer.parseInt(nodeList.get(14).toString()));
        addSal.setString(13, nodeList.get(15).toString());
        addSal.executeUpdate();
         demo.commit();

         return true;

    } catch (SQLException ex) {
        demo.rollback(savePoint);

        Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
    }

    return false;
}

these are two tables and im trying to add that data in my first attempt failed but not store due roll back

【问题讨论】:

  • 重复键异常意味着数据库中某个键的数据已经存在。鉴于您尚未发布minimal reproducible example,我们无法为您提供帮助,因为我们不知道您的表的定义及其约束,也不知道您尝试插入的数据或数据库中已经存在的数据,您也没有包含完整的异常堆栈跟踪。
  • 另外,如果您使用 MySQL,请确保您的表是 InnoDB,MyISAM 不支持事务,因此回滚或提交对这些表类型没有任何作用。问题也可能是您只回滚到保存点,但尚未回滚或提交整个事务。保存点仅用于回滚事务的一部分:事务本身也需要提交或回滚。
  • 我已经添加了表定义图像的链接,这些是 InnoDB。事务如何回滚??
  • 使用demo.rollback(),并删除您的保存点使用:它不会为您的代码添加任何内容。无论如何,不​​要发布图片,发布实际的DDL。

标签: java mysql jdbc


【解决方案1】:

您的代码中有 2 个 INSERT 语句。
第一个为designation 表:

"INSERT INTO `designation`(`desig_id`,`dept_id`,`desig_name`,`desig_desc`) VALUES (?,?,?,?)"

这里看起来desig_id 是主键(可能是自动增量,在这种情况下您根本不能提供值)。
您确定您为此列提供的值不存在于表中吗?

salary 表的第二个:

"INSERT INTO `salary` " + "(`desig_id`, `basic`, `house_rent`, `conveyance`, `medical`, `dearness`,`others_allowances`," + " `income_tax`, `pro_tax`, `emp_state_insu`, `absence_fine`, `others_deductions`, `month`)" + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"

在这种情况下不清楚,因为您没有发布表的CREATE 语句,这是主键。
因此,您必须检查该值(或多列键的值)是否违反了键的唯一性。

【讨论】:

  • 我已经添加了表格图片的链接 请检查...如果我在输入数据时没有犯任何错误,一切都很好...如果我添加了一些导致错误的数据而不是回滚插入但我无法再次存储该 emp_id
  • 我在 2 个表中都没有看到 emp_id 列。
  • 对不起..它的设计ID不是emp_id..我忘了:)
  • 在表salary 中,主键是id,因为您没有在INSERT 语句中提供值,所以它必须是自增的,所以这个插入应该没有问题。问题出在designation 表中吗?我看到组成主键的 2 个字段:iddesig_id。对于这些,您必须检查这些值是否可以创建重复项。
猜你喜欢
  • 2017-08-02
  • 2011-06-26
  • 1970-01-01
  • 2016-01-16
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
  • 1970-01-01
相关资源
最近更新 更多