Comment prévenir le problème de concurrence dans la mise à JOUR via iBatis
Notre Java EE web application effectue les opérations de base de données à l'aide de iBatis (ORM). L'opération de base de données de flux est comme ci-dessous
Flux : JSP --->Action--->ServiceIMpl--->DaoImpl---->Appel de requête de mise à jour thru' IBatis
Note: L'Action, Service & classes DAO sont instanciés à l'aide de Spring 2.5 de l'Injection de Dépendance technique. Nous utilisons Struts2.
Problème: 2 utilisateurs simultanés de recherche pour le même enregistrement et mises à jour Utilisateur1 Attribut1 alors que User2 mises à jour Attribut2. User1 premier clique sur "Enregistrer" puis User2 clique sur enregistrer (ils suivent les uns les autres avec une différence de quelques secondes). Quand nous voyons les données dans la base de données, seul l'Utilisateur1 mise à jour est présent. La Vérification par ailleurs, les colonnes montrent seulement l'Utilisateur1 mise à jour. Le User2 de mise à jour sur Attribut2 n'est pas fait , à la sametime, aucune exception n'est levée.
Nous avons essayé en utilisant le début de la transaction et de la transaction de validation dans iBatis entourant la invokation de la requête de mise à jour défini dans le sqlmap xml. Le même problème persiste. Nous avons également essayé de supprimer les commandes de transactions, mais le problème persiste.
Devrions-nous faire quelque chose de spécial/différentes pour gérer la simultanéité lors des mises à jour ? Ne serait pas Orm comme iBatis gérer par eux-mêmes ?
Informations supplémentaires: une enquête ultérieure a révélé les informations suivantes.
Quand User1 & User2 clique sur l'un enregistrement complet de l'extraction des données pour l'affichage.
Maintenant, quand les deux User1 & User2 changements de quelques attributs, puis cliquez sur save (simultanément), dire que la première Utilisateur1 données est mise à jour et puis tout User2 de données est en cours de mise à jour, la mise à jour des données de l'utilisateur User1 est écrit & perdu.
What approach is usually followed in such screens to handle such scenarios ?
j'ai mis à jour la question avec quelques mises à jour..
OriginalL'auteur yathirigan | 2012-09-27
Vous devez vous connecter pour publier un commentaire.
Votre problème n'est pas avec des transactions, c'est qu'avant de modifier quelque chose que vous devez être sûr que personne n'a modifié depuis votre dernière lecture.
Dans les applications web, vous devez utiliser le verrouillage optimiste. Fondamentalement, vous avez une "version" du champ dans votre table, qui a une valeur initiale à
insert
(typiquement 1), et est incrémenté à chaqueupdate
. La procédure est la suivante:Lire les données de la table, y compris le champ version
Envoyer des données côté client, y compris le champ version
Recevoir des données modifiées par le client, y compris le champ version inchangé
Mise à jour de la table et incrémentation de la version, mais seulement si le champ version en ligne est le même que celui d'origine a reçu de la part du client. C'est là où vous aviez
vous pouvez maintenant faire
Obtenir le nombre de lignes mises à jour (vous pouvez généralement obtenir ces informations à droite à partir de l'opération de mise à jour de votre infrastructure de persistance). Si le nombre de lignes mises à jour est de 1, l'opération a réussi. Si le nombre de lignes mises à jour est 0, vous devez signal d'une simultanéité d'erreur.
Un exemple:
User1 obtenir les données, avec la version = 17
User2 obtenir les données, avec la version = 17
User1 automatiquement (atomicité d'une seule instruction SQL):
User2 atomiquement:
Le plus courant de la persistance des cadres de soutien pour cette sortie de la boîte et la plupart du temps automatiquement (voir JPA @Version annotation, par exemple). iBatis ne semble pas l'avoir, mais comme il est très proche de SQL, vous ne devriez pas avoir beaucoup de problèmes de mise en œuvre vous-même. Voir cette entrée de blog pour quelques détails sur le verrouillage optimiste avec iBatis.
Avec ce régime, vous ne serez pas perdu mises à jour, le seul problème est que certains cas spécifiques ennuyer les utilisateurs beaucoup: imaginez-vous passer 5 minutes pour remplir une certaine forme seulement d'être dit à la fin de votre opération n'a pas pu être terminé et que vous avez besoin pour recommencer depuis le début!! Dans ces quelques cas, vous devez mettre en œuvre quelque chose de plus sophistiqué sur le dessus de verrouillage optimiste. Je voudrais utiliser une sorte de ressource éloignée de location (liens??):
Le client demande un location pour les données au serveur.
Si les données sont déjà loués à un autre client, le signal d'une simultanéité d'erreur.
D'autre octroyer le contrat de location, le client pour une quantité limitée de temps.
Avant l'expiration du bail, le serveur accorde au client un accès exclusif aux données. Le client peut aussi demander un renouvellement de bail (via AJAX, par exemple). Le serveur peut accepter ou refuser le renouvellement. (Les durées de bail et le renouvellement des politiques devrait être décidé par le serveur en fonction du cas d'utilisation qui est en cours de traitement).
L'expiration du bail (ce qui peut être fait avec une tâche planifiée sur le serveur, par exemple). Lorsque le bail expire, les données doivent être considérées comme "déverrouillé", et le serveur doit refuser l'accès pour le client, sauf si le client est accordé un nouveau contrat de location.
De cette façon, vos utilisateurs peuvent être informés que quelqu'un est en train de modifier les mêmes données avant qu'ils commencent même à quelle opération longue, ils ont été en essayant de terminer.
Vous avez raison, c'est juste que dire "le verrouillage pessimiste" implique de verrouillage indéfiniment au niveau de décibels à beaucoup de gens (moi y compris). Je préfère les appeler "contrat de location" à la des approches semblables à ce que j'ai décrit, et laisser "le verrouillage pessimiste" pour
LOCK TABLE...
,SELECT ... FOR UPDATE
et ce genre de choses.je vous remercie pour le temps de vous fournir une réponse détaillée. Lors de la lecture sur l'Optimiste & verrouillage Pessimiste concepts, j'ai aussi été en regardant autour si iBatis ORM prennent en charge toutes ces fonctionnalités out-of-the-box, mais on dirait que ce n'est pas, contrairement à la JPA ORM.
j'ai commencé à regarder les options pour inclure le verrouillage Optimiste fonction en tant que ré-utilisable à l'aide d'AOPs au Printemps ou à l'aide d'AspectJ .. tous les pointeurs/directions sont les bienvenus....
OriginalL'auteur gpeche
Ibatis ne pas effectuer de verrouillage .Voir le vôtre scénario optimiste de verrouillage peut résoudre le problème.Pour réaliser le verrouillage optimiste, vous pouvez avoir des options.
1.L'utilisation du cadre de l'appui pour la gestion des transactions comme org.springframework.jdbc.source de données.
DataSourceTransactionManager.Ils fournissent de propagation de comportement et le niveau d'isolation.Mais,la source de données que vous utilisez doit prendre en niveau de propagation et le niveau d'isolation.Printemps suivant le niveau d'isolation.
.ISOLATION_DEFAULT
.ISOLATION_READ_UNCOMMITTED
.ISOLATION_READ_COMMITTED
.ISOLATION_REPEATABLE_READ
.ISOLATION_SERIALIZABLE.
2.Ensuite, vous pouvez fournir le vôtre de mise en œuvre de verrouillage optimiste.
OriginalL'auteur abishkar bhattarai