跟踪SQL中的新主键

时间:2011-12-05 11:50:51

标签: java sql sqlite jdbc transactions

对不起,这是一个很长的问题,但它触及了数据库的一般问题:

我正在使用sqlite / jdbc(在本例中),我正在尝试跟踪在向表中添加行时创建的自动ID。数据库有一个主表'Person'和其他名为'training'和'induction'的表。这个想法是人名和其他基本细节进入“人”表,而且一个人很多都有很多“训练”和“归纳”。所以,我可以通过SELECT * FROM INDUCTIONS WHERE PERSON_ID = any来查找给定人物的所有归纳。

问题在于创建数据库,我必须添加一个人,然后跟踪他们获得的AUTOINCREMENTing ID,然后在另一个表中创建具有该ID作为外键的条目:

所以

int id = 0;    
PreparedStatement prepPerson = conn.prepareStatement("insert into persons values (?, ?);");
prepPerson.setString(2, p.getName());
prepPerson.addBatch();

然后

PreparedStatement prepInductions = conn.prepareStatement("insert into inductions values (?, ?, ?, ?);");

Then loop over all the inductions {
prepInductions.setInt(2, id);
prepInductions.setString(3, i.getSite());
prepInductions.setString(4, i.getExpiryDate());
prepInductions.addBatch();
}

我希望与数据库的交互是“原子的”,所以我想做

prepPerson.executeBatch();
prepInductions.executeBatch();
id++;

我意识到可以改为添加person,执行getGeneratedKeys(),然后使用新人的正确row_id添加导入,但我不希望在添加Person之后但在导入之前发生异常。如果发生这种情况,那么我将不得不回滚时间并将其移除。

目前我知道我每次都从外部源重新创建数据库,我用一个本地整数变量跟踪row_id,我知道这是生活危险。

这种情况不存在一般解决方案吗?或者我是否担心与数据库的“原子”交互?

3 个答案:

答案 0 :(得分:2)

使用getGeneratedKeys()检索生成的ID。

要保持数据完整性,请使用事务。通常,JDBC使用“autoCommit”模式,但在这种情况下,您需要手动处理事务。

在您的连接上致电.setAutoCommit(false),然后使用.commit().rollback()提交或放弃更改。

(检查Connection Javadoc。)

答案 1 :(得分:0)

对于这样的场景,一般框架是......

Begin A Transaction

 Create your primary entry
 Collect the auto-generated key
 Create your child entries

Commit The Transaction

如果任何步骤失败,则允许您Rollback the Transaction

在SQLite中,我相信last_insert_rowid()可用于在首次插入后获取自动生成的ID。

答案 2 :(得分:0)

您可以使用上面提供的代码,但请确保关闭自动提交。然后,您需要在加载所有人的导入后手动提交事务。如果遇到错误,请将其回滚。

这完全是原子的。