[Building Sakai] weird performance problem in hibernate

Hedrick Charles hedrick at rutgers.edu
Wed Feb 19 14:11:44 PST 2014


The problem was with a pathological site. It has 2,000,000 items, mostly on deleted pages. I can guess how it happened. Quite likely from multiple imports of contents. We’ve fixed a couple of things that would contribute to that.

On Feb 19, 2014, at 3:50:40 PM, Noah Botimer <botimer at umich.edu> wrote:

> This is just a generalization / ballpark idea... When touching lots of "overlapping" items in OSP (for export/stats), we ran into some vaguely similar issues.
> 
> In those cases, there were tons of L2 cache checks, etc. Basically, every copy of the same entity in a different list has to be synchronized unless it is evicted from the Hibernate session. This is kind of on the boundary between OLTP and OLAP. More specifically, this kind of operation is read-heavy and is wide and deep, but does not need much in the way of transactional support or isolation. You probably don't care about caching or any updates to the entities, right?
> 
> You may be able to improve things with a few techniques. First, I'd look at adjusting the propagation to "supports", which means a transaction will be joined or not required at the service boundary, rather than the usual default "required", which can spawn lots of costly extras. Second, if you really just need the IDs, I'd look at using an HQL query that returns a primitive array, rather than deserializing entities (and registering them with the cache). The third thing (if not doing the second), would be to audit all of the lazy collections in the chain and make sure that anything you traverse is fetched eagerly -- this might dovetail with getting out of the HibernateTemplate model and using the Hibernate Session/Criteria API directly, which is recommended but can be a lot of work.
> 
> http://docs.spring.io/spring/docs/3.2.3.RELEASE/spring-framework-reference/html/transaction.html
> http://docs.spring.io/spring/docs/3.2.3.RELEASE/javadoc-api/org/springframework/transaction/annotation/Propagation.html
> 
> Thanks,
> -Noah
> 
> On Feb 19, 2014, at 2:33 PM, Charles Hedrick wrote:
> 
>> Can anyone make suggestions with this?
>> 
>> In Lessons, when exporting and copying, I sometimes need to find all items on any page of the site. I use code like this:
>> 
>>        public List<SimplePageItem> findTextItemsInSite(String siteId) {
>>            Object [] fields = new Object[1];
>>            fields[0] = siteId;
>>            List<String> ids = sqlService.dbRead("select b.id from lesson_builder_pages a,lesson_builder_items b where a.siteId = ? and a.pageId = b.pa\
>> geId and b.type = 5", fields, null);
>> 
>>            List<SimplePageItem> result = new ArrayList<SimplePageItem>();
>> 
>>            if (result != null) {
>>                for (String id: ids) {
>>                    SimplePageItem i = findItem(new Long(id));
>>                    result.add(i);
>>                }
>>            }
>>            return result;
>>        }
>> 
>> 
>> I realie that this isn’t optimal, but it’s also not done very often, so it shouldn’t be an issue. But I recently found a thread that was doing an export, where the equivalent code looking for all text items took hours and didn’t show any sign of ending. I include a stack trace at the end of this message.
>> 
>> What I’ve done for that case is avoid hibernate entirely. I just need a couple of fields from the items, so the query returns them and I generate items myself that just have those fields filled in. But I have methods like this returning other sets of items. In principle I can do the same thing for all of them, but do I have to? Anyone have idea idea why this is taking so long? It’s hard to believe that this would ever result in more than a few hundred items. Is there some pitfall I don’t know about in fetching that many items and putting them in a list?
>> 
>> 
>> java.lang.Class.getInterfaces(Native Method)
>> org.hibernate.intercept.FieldInterceptionHelper.extractFieldInterceptor(FieldInterceptionHelper.java:45)
>> org.hibernate.intercept.FieldInterceptionHelper.clearDirty(FieldInterceptionHelper.java:81)
>> org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:209)
>> org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:127)
>> org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
>> org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
>> org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
>> org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:970)
>> org.hibernate.impl.SessionImpl.list(SessionImpl.java:1563)
>> org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
>> org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1065)
>> org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
>> org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
>> org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1055)
>> org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:1048)
>> org.sakaiproject.lessonbuildertool.model.SimplePageToolDaoImpl.findItem(SimplePageToolDaoImpl.java:270)
>> org.sakaiproject.lessonbuildertool.model.SimplePageToolDaoImpl.findTextItemsInSite(SimplePageToolDaoImpl.java:230)
>> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>> java.lang.reflect.Method.invoke(Method.java:606)
>> org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
>> org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
>> org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
>> org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>> com.sun.proxy.$Proxy62.findTextItemsInSite(Unknown Source)
>> org.sakaiproject.lessonbuildertool.ccexport.CCExport.outputAllTexts(CCExport.java:607)
>> org.sakaiproject.lessonbuildertool.ccexport.CCExport.download(CCExport.java:1030)
>> org.sakaiproject.lessonbuildertool.ccexport.CCExport.doExport(CCExport.java:214)
>> 
>> 
>> _______________________________________________
>> sakai-dev mailing list
>> sakai-dev at collab.sakaiproject.org
>> http://collab.sakaiproject.org/mailman/listinfo/sakai-dev
>> 
>> TO UNSUBSCRIBE: send email to sakai-dev-unsubscribe at collab.sakaiproject.org with a subject of "unsubscribe"
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://collab.sakaiproject.org/pipermail/sakai-dev/attachments/20140219/ee8af3cd/attachment.html 


More information about the sakai-dev mailing list