Bonjour,
J'utilise Hibernate pour des EJB3 avec la base de données Derby sur GlassFish V2UR1.
J'ai actuellement un problème ennuyeux. Ma base de données contient des alertes qui peuvent être consultées/modifiées continuellement.
Un EJB session s'occupe avec son entity manager de faire tous les accés à la base de données.
J'ai un problème de verrous sur des SELECT et je ne sais pas trop quoi faire ...
L'erreur est
[#|2008-04-16T11:11:28.973+0200|WARNING|sun-appserver9.1|org.hibernate.util.JDBCExceptionReporter|_ThreadID=81;_ThreadName=p: thread-pool-1; w: 64;_RequestID=0c72b586-ece1-43b2-9961-0a4f73992014;|SQL Error: -1, SQLState: 40001|#]
[#|2008-04-16T11:11:28.973+0200|SEVERE|sun-appserver9.1|org.hibernate.util.JDBCExceptionReporter|_ThreadID=81;_ThreadName=p: thread-pool-1; w: 64;_RequestID=0c72b586-ece1-43b2-9961-0a4f73992014;|Aucun verrou n'a pu être obtenu à cause d'un interblocage ; le cycle de verrous et d'unités en attente est :
Lock : ROW, ALERT, (1814,7)
Waiting XID : {175003, S} , APP, select distinct alert0_.USERID as col_0_0_ from Alert alert0_
Granted XID : {174982, X}
Lock : ROW, ALERT, (1815,6)
Waiting XID : {174982, S} , APP, select distinct alert0_.USERID as col_0_0_ from Alert alert0_
Granted XID : {175003, X}
. L'instruction SQL que le moteur de la base de données a choisi de supprimer est XID : 175003.|#]
[#|2008-04-16T11:11:28.988+0200|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=81;_ThreadName=p: thread-pool-1; w: 64;UserAlert;|EJB5018: An exception was thrown during an ejb invocation on [UserAlert]|#]
[#|2008-04-16T11:11:28.988+0200|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=81;_ThreadName=p: thread-pool-1; w: 64;|
javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: javax.persistence.PersistenceException: org.hibernate.exception.LockAcquisitionException: could not execute query
javax.persistence.PersistenceException: org.hibernate.exception.LockAcquisitionException: could not execute query
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:641)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:73)
at com.monitor.ejb.alert.UserAlertBean.findAllUsers(UserAlertBean.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1067)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:176) ....
at org.hibernate.loader.Loader.list(Loader.java:2023)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:393)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64)
... 28 more
Caused by: java.sql.SQLTransactionRollbackException: Aucun verrou n'a pu être obtenu à cause d'un interblocage ; le cycle de verrous et d'unités en attente est :Lock : ROW, ALERT, (1814,7)
Waiting XID : {175003, S} , APP, select distinct alert0_.USERID as col_0_0_ from Alert alert0_
Granted XID : {174982, X}
Lock : ROW, ALERT, (1815,6)
Waiting XID : {174982, S} , APP, select distinct alert0_.USERID as col_0_0_ from Alert alert0_
Granted XID : {175003, X}
. L'instruction SQL que le moteur de la base de données a choisi de supprimer est XID : 175003.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.executeQuery(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1668)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2144)
... 36 more
Les méthodes de mon session EJB qui appellent derby sont
Les fichiers de config hibernate sont
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 /** * Find all user ID for current Alert. * @return a List of user ID */ public Collection < String > findAllUsers() { List result = manager.createNamedQuery("findAllUsers").getResultList(); manager.flush(); return result; } /** * Remove an alert. * @param id the unique Alert's ID * @param flush boolean to define if must flush information * as we processed many items */ public void removeAlert(Long id) { Alert alertToRemove = manager.find(Alert.class, id); if (alertToRemove != null) { manager.remove(alertToRemove); } manager.flush(); } /** * Find Alerts object for a given User ID. * @param userId the unique id * @return a collection of Alert object */ public Collection < Alert > findAlertsForUser(String userId) { log.info("will extract info for : " + userId); Query query = manager.createNamedQuery("findByUserid") .setParameter("user", userId); List result = query.getResultList(); manager.flush(); return result; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 <hibernate-mapping> <class name="com.monitor.ejb.alert.Alert" table="alert"> <id name="id" type="long" column="ID" > <generator class="increment"/> </id> <property name="userid"> <column name="USERID" sql-type="char(10)" not-null="true"/> </property> <property name="message"> <column name="MESSAGE" sql-type="char(2000)" not-null="true"/> </property> </class> </hibernate-mapping>Que pourrais-je faire pour en finir avec ce blocage ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property> <property name="hibernate.connection.url">jdbc:derby://127.0.0.1:1527/</property> <property name="hibernate.connection.username">admin</property> <property name="hibernate.connection.password">adminadmin</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">hibernate.dialect=org.hibernate.dialect.DerbyDialect</property> <property name="hibernate.hbm2ddl.auto">create</property> <!-- Mapping files --> <mapping resource="com.monitor.ejb.alert.Alert.hbm.xml"/> </session-factory> </hibernate-configuration>
Puis je changer quelque chose pour q'un select puisse accéder aux données sans verrou ?
Merci
Franck
Partager