Tôi có hai bảng trong cơ sở dữ liệu MySQL của tôi, mà đã được tạo ra như thế này:JDBC: khoá ngoại trên PK tạo ra trong cùng một giao dịch
CREATE TABLE table1 (
id int auto_increment,
name varchar(10),
primary key(id)
) engine=innodb
và
CREATE TABLE table2 (
id_fk int,
stuff varchar(30),
CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE
) engine=innodb
(Đây không phải là bảng gốc Điểm là bảng 2 có khóa ngoài tham chiếu khóa chính trong bảng 1)
Bây giờ trong mã của tôi, tôi muốn thêm mục vào cả hai bảng trong một giao dịch. Vì vậy, tôi đặt autoCommit
false:
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
}
Khi tôi thực thi mã trên, tôi nhận được một ngoại lệ:
MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
Nó có vẻ như khóa chính là không có sẵn trong giao dịch trước khi tôi cam kết.
Tôi có thiếu gì đó ở đây không? Tôi thực sự nghĩ rằng khóa chính được tạo nên có sẵn trong giao dịch.
Chương trình chạy trên Glassfish 3.0.1 sử dụng kết nối mysql 5.1.14 và MySQL 5.5.8
Bất kỳ trợ giúp nào thực sự được đánh giá cao!
Kính trọng, Hage
Cảm ơn bạn! Nó hoạt động hoàn hảo ngay bây giờ. Nhưng điều gì đó vẫn chưa rõ ràng với tôi: Các bảng của tôi trống trước khi tôi chạy mã. Vì vậy, 'exececuteUpdate' trả về số hàng bị ảnh hưởng (trong trường hợp này 1) cũng là ID được tạo. Tôi nghĩ rằng điều này nên đã làm việc quá - cũng có thể nó đã đưa ra ngoại lệ trong một lần chạy thứ hai ... Hoặc không 'getGeneratedKeys()' làm cho các phím có sẵn? – hage
Id hàng được chèn bắt đầu đến hàng cuối cùng + 1, trừ khi bạn thực hiện 'cắt ngắn' trên bảng của mình, nó sẽ không được khởi tạo thành 0. – EricParis16
+1 Tôi đang tìm câu trả lời này trong thời gian dài –