You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Gabriela Matias Navarro <na...@gmail.com> on 2016/01/21 11:35:22 UTC

Save session recommendation on loops

Hello,

I'm working on a method that deletes some documents using the "removeItem"
method from Sessions(link
<https://jackrabbit.apache.org/api/1.6/org/apache/jackrabbit/api/jsr283/Session.html#removeItem(java.lang.String)>).
First the method searchs the documents that needs to be deleted and then it
iterates over the list and deletes each one of them and saves the session
inside the loop. Since we are using a cluster of jackrabbit instances we
are getting some conflicts. I wanted to know if there is a recommendation
on where the save session should be(inside the loop or after the loop)?

Thanks,

Gabriela

Re: Save session recommendation on loops

Posted by Clay Ferguson <wc...@gmail.com>.
You definitely don't want to save a session after each node delete. You
should delete them in batches of 100 to 500 in my opinion. So it's not a
matter of deleting them one by time, or deleting them all, with one save at
the end, because either way that's a risk of too much temporary work cached
up to be done at once. JCRs aren't transactional acid, so just make your
code eat away blocks of deletes in chunks of 100, until it's out of work to
do. This my two cents worth.

Best regards,
Clay Ferguson
wclayf@gmail.com


On Thu, Jan 21, 2016 at 1:02 PM, Gabriela Matias Navarro <
navarro1703@gmail.com> wrote:

> Hi Beth,
>
> Thanks :)
>
> I followed the exception that I got and this is my theory:
>
> The fact that I'm saving the session for each document removal is causing
> problems with the database. Since I'm running a cluster and more than one
> node can run this method at the same time, I think it's causing errors when
> it tries to lock the global table(because more than one node is probably
> saving the session at the same time) and is causing the database to
> deadlock.
>
> This is my theory based on the exception:
>
> Unable to update item: item.save()
> org.apache.jackrabbit.core.state.ItemStateException: Unable to create log entry: Unable to lock global revision table.
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:575)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1507)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1537)
> 	at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:400)
> 	at org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
> 	at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:375)
> 	at org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:275)
> 	at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:258)
> 	at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
> 	at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91)
> 	at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:329)
> 	at org.apache.jackrabbit.core.session.SessionSaveOperation.perform(SessionSaveOperation.java:65)
> 	at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
> 	at org.apache.jackrabbit.core.SessionImpl.perform(SessionImpl.java:361)
> 	at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:812)
> 	at com.hp.ccp.jcr.impl.JCRDAO.deleteDocumentOlderThan(JCRDAO.java:2805)
> 	at com.hp.ccp.ccpsrv.document.impl.RiptideServicesImpl.deleteDocumentOlderThan(RiptideServicesImpl.java:2271)
> 	at com.hp.ccp.ccpsrv.document.impl.DocumentDeletingProcessor.process(DocumentDeletingProcessor.java:213)
> 	at com.hp.ccp.ccpsrv.document.impl.DocumentDeletingHandler.handleEvent(DocumentDeletingHandler.java:33)
> 	at org.apache.felix.eventadmin.impl.tasks.HandlerTaskImpl.execute(HandlerTaskImpl.java:87)
> 	at org.apache.felix.eventadmin.impl.tasks.SyncDeliverTasks$1.run(SyncDeliverTasks.java:238)
> 	at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(Unknown Source)
> 	at java.lang.Thread.run(Thread.java:745)
> Caused by: org.apache.jackrabbit.core.cluster.ClusterException: Unable to create log entry: Unable to lock global revision table.
> 	at org.apache.jackrabbit.core.cluster.ClusterNode$WorkspaceUpdateChannel.updateCreated(ClusterNode.java:639)
> 	at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:573)
> 	... 22 more
> Caused by: org.apache.jackrabbit.core.journal.JournalException: Unable to lock global revision table.
> 	at org.apache.jackrabbit.core.journal.DatabaseJournal.doLock(DatabaseJournal.java:509)
> 	at org.apache.jackrabbit.core.journal.AbstractJournal.internalLockAndSync(AbstractJournal.java:333)
> 	at org.apache.jackrabbit.core.journal.AbstractJournal.lockAndSync(AbstractJournal.java:312)
> 	at org.apache.jackrabbit.core.journal.DefaultRecordProducer.append(DefaultRecordProducer.java:51)
> 	at org.apache.jackrabbit.core.cluster.ClusterNode$WorkspaceUpdateChannel.updateCreated(ClusterNode.java:635)
> 	... 23 more
> Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
> 	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
> 	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
> 	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
> 	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
> 	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
> 	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2819)
> 	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2768)
> 	at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:894)
> 	at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:732)
> 	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
> 	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
> 	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
> 	at org.apache.jackrabbit.core.util.db.ConnectionHelper.reallyExec(ConnectionHelper.java:309)
> 	at org.apache.jackrabbit.core.util.db.ConnectionHelper$1.call(ConnectionHelper.java:294)
> 	at org.apache.jackrabbit.core.util.db.ConnectionHelper$1.call(ConnectionHelper.java:290)
> 	at org.apache.jackrabbit.core.util.db.ConnectionHelper$RetryManager.doTry(ConnectionHelper.java:552)
> 	at org.apache.jackrabbit.core.util.db.ConnectionHelper.exec(ConnectionHelper.java:290)
> 	at org.apache.jackrabbit.core.journal.DatabaseJournal.doLock(DatabaseJournal.java:501)
> 	... 27 more
>
>
> Can you tell me if my theory makes sense? :)
>
>
> Thanks,
>
>
> Gabriela
>
>
> 2016-01-21 8:43 GMT-02:00 Beth Seabloom <be...@gmail.com>:
>
>> Hi Gabriela,
>> Inside the loop I would save a list of paths to remove. Then, after
>> locating everything to delete, loop through the paths to remove, calling
>> remove for each. Then it's up to you if you want to save after each or
>> after all of them have been removed -  it depends on how many you are
>> removing and how long the save takes.
>>
>> Beth
>>
>> On Jan 21, 2016, at 5:35 AM, Gabriela Matias Navarro <
>> navarro1703@gmail.com> wrote:
>>
>> Hello,
>>
>> I'm working on a method that deletes some documents using the "removeItem"
>> method from Sessions(link
>> <https://jackrabbit.apache.org/api/1.6/org/apache/jackrabbit/api/jsr283/Session.html#removeItem(java.lang.String)>).
>> First the method searchs the documents that needs to be deleted and then it
>> iterates over the list and deletes each one of them and saves the session
>> inside the loop. Since we are using a cluster of jackrabbit instances we
>> are getting some conflicts. I wanted to know if there is a recommendation
>> on where the save session should be(inside the loop or after the loop)?
>>
>> Thanks,
>>
>> Gabriela
>>
>>
>

Re: Save session recommendation on loops

Posted by Gabriela Matias Navarro <na...@gmail.com>.
Hi Beth,

Thanks :)

I followed the exception that I got and this is my theory:

The fact that I'm saving the session for each document removal is causing
problems with the database. Since I'm running a cluster and more than one
node can run this method at the same time, I think it's causing errors when
it tries to lock the global table(because more than one node is probably
saving the session at the same time) and is causing the database to
deadlock.

This is my theory based on the exception:

Unable to update item: item.save()
org.apache.jackrabbit.core.state.ItemStateException: Unable to create
log entry: Unable to lock global revision table.
	at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:575)
	at org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1507)
	at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1537)
	at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:400)
	at org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
	at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:375)
	at org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:275)
	at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:258)
	at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
	at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91)
	at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:329)
	at org.apache.jackrabbit.core.session.SessionSaveOperation.perform(SessionSaveOperation.java:65)
	at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
	at org.apache.jackrabbit.core.SessionImpl.perform(SessionImpl.java:361)
	at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:812)
	at com.hp.ccp.jcr.impl.JCRDAO.deleteDocumentOlderThan(JCRDAO.java:2805)
	at com.hp.ccp.ccpsrv.document.impl.RiptideServicesImpl.deleteDocumentOlderThan(RiptideServicesImpl.java:2271)
	at com.hp.ccp.ccpsrv.document.impl.DocumentDeletingProcessor.process(DocumentDeletingProcessor.java:213)
	at com.hp.ccp.ccpsrv.document.impl.DocumentDeletingHandler.handleEvent(DocumentDeletingHandler.java:33)
	at org.apache.felix.eventadmin.impl.tasks.HandlerTaskImpl.execute(HandlerTaskImpl.java:87)
	at org.apache.felix.eventadmin.impl.tasks.SyncDeliverTasks$1.run(SyncDeliverTasks.java:238)
	at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.jackrabbit.core.cluster.ClusterException: Unable
to create log entry: Unable to lock global revision table.
	at org.apache.jackrabbit.core.cluster.ClusterNode$WorkspaceUpdateChannel.updateCreated(ClusterNode.java:639)
	at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:573)
	... 22 more
Caused by: org.apache.jackrabbit.core.journal.JournalException: Unable
to lock global revision table.
	at org.apache.jackrabbit.core.journal.DatabaseJournal.doLock(DatabaseJournal.java:509)
	at org.apache.jackrabbit.core.journal.AbstractJournal.internalLockAndSync(AbstractJournal.java:333)
	at org.apache.jackrabbit.core.journal.AbstractJournal.lockAndSync(AbstractJournal.java:312)
	at org.apache.jackrabbit.core.journal.DefaultRecordProducer.append(DefaultRecordProducer.java:51)
	at org.apache.jackrabbit.core.cluster.ClusterNode$WorkspaceUpdateChannel.updateCreated(ClusterNode.java:635)
	... 23 more
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try
restarting transaction
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2819)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2768)
	at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:894)
	at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:732)
	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
	at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
	at org.apache.jackrabbit.core.util.db.ConnectionHelper.reallyExec(ConnectionHelper.java:309)
	at org.apache.jackrabbit.core.util.db.ConnectionHelper$1.call(ConnectionHelper.java:294)
	at org.apache.jackrabbit.core.util.db.ConnectionHelper$1.call(ConnectionHelper.java:290)
	at org.apache.jackrabbit.core.util.db.ConnectionHelper$RetryManager.doTry(ConnectionHelper.java:552)
	at org.apache.jackrabbit.core.util.db.ConnectionHelper.exec(ConnectionHelper.java:290)
	at org.apache.jackrabbit.core.journal.DatabaseJournal.doLock(DatabaseJournal.java:501)
	... 27 more


Can you tell me if my theory makes sense? :)


Thanks,


Gabriela


2016-01-21 8:43 GMT-02:00 Beth Seabloom <be...@gmail.com>:

> Hi Gabriela,
> Inside the loop I would save a list of paths to remove. Then, after
> locating everything to delete, loop through the paths to remove, calling
> remove for each. Then it's up to you if you want to save after each or
> after all of them have been removed -  it depends on how many you are
> removing and how long the save takes.
>
> Beth
>
> On Jan 21, 2016, at 5:35 AM, Gabriela Matias Navarro <
> navarro1703@gmail.com> wrote:
>
> Hello,
>
> I'm working on a method that deletes some documents using the "removeItem"
> method from Sessions(link
> <https://jackrabbit.apache.org/api/1.6/org/apache/jackrabbit/api/jsr283/Session.html#removeItem(java.lang.String)>).
> First the method searchs the documents that needs to be deleted and then it
> iterates over the list and deletes each one of them and saves the session
> inside the loop. Since we are using a cluster of jackrabbit instances we
> are getting some conflicts. I wanted to know if there is a recommendation
> on where the save session should be(inside the loop or after the loop)?
>
> Thanks,
>
> Gabriela
>
>

Re: Save session recommendation on loops

Posted by Beth Seabloom <be...@gmail.com>.
Hi Gabriela,
Inside the loop I would save a list of paths to remove. Then, after locating everything to delete, loop through the paths to remove, calling remove for each. Then it's up to you if you want to save after each or after all of them have been removed -  it depends on how many you are removing and how long the save takes. 

Beth

> On Jan 21, 2016, at 5:35 AM, Gabriela Matias Navarro <na...@gmail.com> wrote:
> 
> Hello,
> 
> I'm working on a method that deletes some documents using the "removeItem" method from Sessions(link). First the method searchs the documents that needs to be deleted and then it iterates over the list and deletes each one of them and saves the session inside the loop. Since we are using a cluster of jackrabbit instances we are getting some conflicts. I wanted to know if there is a recommendation on where the save session should be(inside the loop or after the loop)? 
> 
> Thanks,
> 
> Gabriela