JDBC:在同一事务中创建的PK上的外键

hag*_*age 9 java mysql transactions

我的MySQL数据库中有两个表,它们是这样创建的:

CREATE TABLE table1 (
  id int auto_increment,
  name varchar(10),
  primary key(id)
) engine=innodb
Run Code Online (Sandbox Code Playgroud)

CREATE TABLE table2 (
  id_fk int,
  stuff varchar(30),
  CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE
) engine=innodb
Run Code Online (Sandbox Code Playgroud)

(这些不是原始表.重点是table2有一个引用表1中主键的外键)

现在在我的代码中,我想在一个事务中向两个表添加条目.所以我设置autoCommit为假:

    Connection c = null;        

    PreparedStatement insertTable1 = null;
    PreparedStatement insertTable2 = null;

    try {
        // dataSource was retreived via JNDI
        c = dataSource.getConnection();
        c.setAutoCommit(false);

        // will return the created primary key
        insertTable1 = c.prepareStatement("INSERT INTO table1(name) VALUES(?)",Statement.RETURN_GENERATED_KEYS);
        insertTable2 = c.prepareStatement("INSERT INTO table2 VALUES(?,?)");

        insertTable1.setString(1,"hage");
        int hageId = insertTable1.executeUpdate();

        insertTable2.setInt(1,hageId);
        insertTable2.setString(2,"bla bla bla");
        insertTable2.executeUpdate();

        // commit
        c.commit();
   } catch(SQLException e) {
        c.rollback();
   } finally {
      // close stuff
   }
Run Code Online (Sandbox Code Playgroud)

当我执行上面的代码时,我得到一个例外:

MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
Run Code Online (Sandbox Code Playgroud)

在提交之前,似乎主键在事务中不可用.

我在这里错过了什么吗?我真的认为生成的主键应该在事务中可用.

该程序使用mysql-connector 5.1.14和MySQL 5.5.8在Glassfish 3.0.1上运行

任何帮助真的很感激!

问候,哈格

小智 5

您错过了返回更新ID的内容,您必须这样做:

Long hageId = null;

try {
    result = insertTable1.executeUpdate();
} catch (Throwable e) {
    ...
}

ResultSet rs = null;

try {
    rs = insertTable1.getGeneratedKeys();
    if (rs.next()) {
        hageId = rs.getLong(1);
    }
 ...
Run Code Online (Sandbox Code Playgroud)