两个CallableStatementS之间的Phantom MySQLIntegrityConstraintViolationException

时间:2015-12-29 14:04:43

标签: java mysql transactions constraints innodb

我们得到了奇怪的非永久性错误:java事务中的MySQLIntegrityConstraintViolationException。         想象一下下一个代码:

SQL:

CREATE TABLE test (
        ruleID INT(11) NOT NULL AUTO_INCREMENT,
        name varchar(250),
        PRIMARY KEY (ruleID)
) engine=InnoDB;


CREATE TABLE test2 (
        ruleID    INT(11) NOT NULL,
        name varchar(250),
        PRIMARY KEY (ruleID),
        CONSTRAINT _FK1 FOREIGN KEY (ruleID)
        REFERENCES test (ruleID)
        ON DELETE CASCADE
) engine=InnoDB;


CREATE PROCEDURE proc1(
        inout p_ruleID INT (11),
        p_name varchar(250)
)
    proc: begin
    IF (p_ruleID < 1) THEN
    INSERT INTO test (ruleID, name) values (null, p_name);
    SELECT LAST_INSERT_ID() INTO p_ruleID;

    else
    UPDATE test
    SET name = p_name
    WHERE ruleID = p_ruleID;

    SELECT p_ruleID;

    END IF;
    END //


CREATE PROCEDURE proc2(
        p_ruleID INT (11),
        p_name varchar(250)
)
    BEGIN
    DELETE FROM test2
    WHERE ruleID = p_ruleID;

    INSERT INTO test2(ruleID, name)
    VALUES (p_ruleID, p_name);

    END //

的java:

    Connection conn;
    int id;
    String name;
    String subName;
    ...

    conn.setAutoCommit(false);
    id=1;

    CallableStatement cs1 = conn.prepareCall("{call proc1(?,?)}");
    cs1.setInt(1, id);
    cs1.setString(2, name);
    cs1.registerOutParameter(1, java.sql.Types.INTEGER);
    cs1.execute();
    int parentID = cs1.getInt(1);
    cs1.close();

    cs1 = conn.prepareCall("{call proc2(?,?)}");
    cs1.setInt(1, parentID);
    cs1.setString(2, subName);
    cs1.execute();
    ...

所以在&#34; cs1.execute()&#34; for&#34; proc2&#34;我们得到了例外:

  

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   无法添加或更新子行:       外键约束失败(test2,CONSTRAINT&#39; _FK1&#39; FOREIGN KEY(&#39; ruleID&#39;)参考&#39; test&#39;(&#39; ruleID&#39;)ON DELETE CASCADE)

我们只得到过一次并且无法重复。 一个&#34;大师&#34;说 - 由Connection执行的java事务,不要保证CallableStatementS之间结果的可见性。 这是真的吗?或者可能是真相在那里?

0 个答案:

没有答案