2009-11-20 6 views
2

J'utilise iBatis/Java et Postgres 8.3. Quand je fais une insertion dans ibatis j'ai besoin de l'id retourné.
J'utilise le tableau suivant pour décrire ma question:
CREATE TABLE sometable (id serial NOT NULL, somefield VARCHAR(10));
La séquence sometable_id_seq obtient en exécutant AutoGénéré l'instruction create.Problèmes de simultanéité lors de la récupération des ID des lignes nouvellement insérées avec ibatis

Au moment j'utiliser la carte sql suivante:

<insert id="insertValue" parameterClass="string" > 
INSERT INTO sometable (somefield) VALUES (#value#); 
<selectKey keyProperty="id" resultClass="int"> 
    SELECT last_value AS id FROM sometable_id_seq 
</selectKey> 
</insert> 

Il semble que ce soit la façon ibatis de récupérer l'ID nouvellement inséré. Ibatis exécute d'abord une instruction INSERT et demande ensuite la séquence du dernier identifiant.
J'ai des doutes que cela fonctionnera avec beaucoup d'insertions concurrentes.

Cela pourrait-il causer des problèmes? Comme retourner l'identifiant du mauvais insert?

(Voir aussi ma question connexe sur how to get ibatis to use the INSERT .. RETURING .. statements)

Répondre

2

C'est certainement faux. Utilisation:

select currval('sometable_id_seq') 

ou mieux encore:

INSERT INTO sometable (somefield) VALUES (#value#) returning id 

qui vous ramènera inséré id.

+0

Alors vous pensez que cela va causer des problèmes. Mon autre question est de savoir comment obtenir la déclaration INSERT INTO .. ​​RETOUR .. en ibatis (Depuis que je ne peux pas poster un lien ici, je l'ai ajouté à la fin de la question) – Christoph

+0

Bien sûr que ce sera le cas. essayez-vous avec 2 connexions de psql. comme pour ibatis - je n'ai aucune idée de ce que c'est, mais ça a l'air java - ce qui veut dire que je ne peux rien faire. –

0

Voici exemple simple:

<statement id="addObject" 
     parameterClass="test.Object" 
     resultClass="int"> 
     INSERT INTO objects(expression, meta, title, 
     usersid) 
     VALUES (#expression#, #meta#, #title#, #usersId#) 
     RETURNING id 
</statement> 

Et dans le code Java:

Integer id = (Integer) executor.queryForObject("addObject", object); 
object.setId(id); 
0

j'ai une autre pensée. ibatis invoque le délégué de la méthode d'insertion de la classe: com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate,with the code:

try { 
     trans = autoStartTransaction(sessionScope, autoStart, trans); 

     SelectKeyStatement selectKeyStatement = null; 
     if (ms instanceof InsertStatement) { 
     selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement(); 
     } 

     // Here we get the old value for the key property. We'll want it later if for some reason the 
     // insert fails. 
     Object oldKeyValue = null; 
     String keyProperty = null; 
     boolean resetKeyValueOnFailure = false; 
     if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) { 
     keyProperty = selectKeyStatement.getKeyProperty(); 
     oldKeyValue = PROBE.getObject(param, keyProperty); 
     generatedKey = executeSelectKey(sessionScope, trans, ms, param); 
     resetKeyValueOnFailure = true; 
     } 

     StatementScope statementScope = beginStatementScope(sessionScope, ms); 
     try { 
     ms.executeUpdate(statementScope, trans, param); 
     }catch (SQLException e){ 
     // uh-oh, the insert failed, so if we set the reset flag earlier, we'll put the old value 
     // back... 
     if(resetKeyValueOnFailure) PROBE.setObject(param, keyProperty, oldKeyValue); 
     // ...and still throw the exception. 
     throw e; 
     } finally { 
     endStatementScope(statementScope); 
     } 

     if (selectKeyStatement != null && selectKeyStatement.isRunAfterSQL()) { 
     generatedKey = executeSelectKey(sessionScope, trans, ms, param); 
     } 

     autoCommitTransaction(sessionScope, autoStart); 
    } finally { 
     autoEndTransaction(sessionScope, autoStart); 
    } 

Vous pouvez voir que l'insert et l'opérateur select sont dans une Transaction. Donc je pense qu'il n'y a pas de problème de concurence avec la méthode insert.