Neo4j Ошибка обновления узлов
Редактировать: На данный момент найдено отвратительное исправление, но по-прежнему нужна помощь в устранении ошибки. Подробности в конце вопроса.
В настоящее время я разрабатываю db/site между neo4j и flask, используя py2neo. Я нахожусь в процессе разработки системы уведомлений, где после действия X пользователи получают уведомление о том, что X имел место. Для этого я создаю новый узел "Обновление" в БД с слиянием.
Дело в том, что если аналогичное действие Y происходит аналогичным образом, я хочу вместо создания нового узла обновления обновить старый. Обычно слияние прекрасно работает, потому что оно должно определить, существует ли узел с этими свойствами, прежде чем создавать новое. У меня проблема в том, что свойства этого узла меняются, например, свойство date_time будет отличаться каждый раз. Из-за этого он создает второй узел обновления для того же типа действия, а не просто обновляет date_time.
Чтобы избежать этого, я делаю следующее:
update = Node('Update', updateUUID = other_node['uuid'])
graph.merge(update)
update['date_time'] = new_date_time
graph.push(update) ## Same error if I use update.push()
rel = Relationship(other_node, 'has_update', update)
graph.create(rel)
Этот метод был предложен другими для обновления существующих узлов. В частности, вызов слияния только с уникальным свойством узла, а затем отправка других данных в него отдельно с помощью push-вызова.
Это прекрасно работает, если рассматриваемый узел уже существовал раньше времени. На самом деле, если я попытаюсь сделать это, он потерпит неудачу только с первой попытки, так как узел частично создается до сбоя. Если я повторю действие X во второй раз, узел обновления будет успешно изменен, перезаписав первый незавершенный узел новыми свойствами.
Наконец, это фактическая ошибка, которую я получаю. Как уже отмечалось, в результате выполнения вышеизложенного сначала будет успешно создан узел со слиянием, но не удастся выполнить обновления, в результате чего у меня останется почти пустой узел в БД.
2017-02-15 00:40:25.636+0000 WARN /db/data/batch Transaction was marked as successful, but unable to commit transaction so rolled back.
org.neo4j.graphdb.TransactionFailureException: Transaction was marked as successful, but unable to commit transaction so rolled back.
at org.neo4j.kernel.impl.coreapi.TopLevelTransaction.close(TopLevelTransaction.java:101)
at org.neo4j.server.rest.transactional.CommitOnSuccessfulStatusCodeRepresentationWriteHandler.closeTransaction(CommitOnSuccessfulStatusCodeRepresentationWriteHandler.java:65)
at org.neo4j.server.rest.transactional.CommitOnSuccessfulStatusCodeRepresentationWriteHandler.onRepresentationFinal(CommitOnSuccessfulStatusCodeRepresentationWriteHandler.java:60)
at org.neo4j.server.rest.web.BatchOperationService$1.write(BatchOperationService.java:137)
at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:71)
at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:57)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:302)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.neo4j.server.rest.dbms.AuthorizationEnabledFilter.doFilter(AuthorizationEnabledFilter.java:122)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.neo4j.kernel.api.exceptions.TransactionFailureException:
at org.neo4j.kernel.impl.api.KernelTransactionImplementation.commit(KernelTransactionImplementation.java:553)
at org.neo4j.kernel.impl.api.KernelTransactionImplementation.closeTransaction(KernelTransactionImplementation.java:484)
at org.neo4j.kernel.api.KernelTransaction.close(KernelTransaction.java:135)
at org.neo4j.kernel.impl.coreapi.TopLevelTransaction.close(TopLevelTransaction.java:79)
... 35 more
Caused by: org.neo4j.kernel.api.exceptions.TransactionHookException: Transaction handler failed.
at org.neo4j.kernel.impl.api.TransactionHooks$TransactionHooksState.add(TransactionHooks.java:102)
at org.neo4j.kernel.impl.api.TransactionHooks.beforeCommit(TransactionHooks.java:61)
at org.neo4j.kernel.impl.api.KernelTransactionImplementation.commit(KernelTransactionImplementation.java:549)
... 38 more
Caused by: com.graphaware.runtime.module.DeliberateTransactionRollbackException: You are not allowed to remove the uuid property
at com.graphaware.module.uuid.UuidModule.beforeCommit(UuidModule.java:143)
at com.graphaware.module.uuid.UuidModule.beforeCommit(UuidModule.java:40)
at com.graphaware.runtime.manager.BaseTxDrivenModuleManager.beforeCommit(BaseTxDrivenModuleManager.java:193)
at com.graphaware.runtime.TxDrivenRuntime.beforeCommit(TxDrivenRuntime.java:76)
at com.graphaware.runtime.TxDrivenRuntime.beforeCommit(TxDrivenRuntime.java:39)
at org.neo4j.kernel.internal.TransactionEventHandlers.beforeCommit(TransactionEventHandlers.java:128)
at org.neo4j.kernel.internal.TransactionEventHandlers.beforeCommit(TransactionEventHandlers.java:50)
... 40 more
После первоначального исследования я был убежден, что это связано с нехваткой места в куче, что имело смысл, потому что в то время я работал на довольно слабой системе. Однако после перехода на новую систему (и повторной установки базы данных практически с нуля с новым файлом конфигурации, в котором не было никаких настроек ограничения кучи), у меня все еще остается та же проблема.
Я немного растерялся, поэтому, если у кого-то есть предложения о том, как это исправить или выполнить то, что я пытаюсь сделать другим способом, чтобы избежать этой проблемы, я был бы очень признателен.
Обновление: Как описано, ошибка появляется только на узлах, которые я создаю впервые. Таким образом, в качестве временной работы до тех пор, пока не будет найдено реальное решение, я просто эмулирую поведение, необходимое для того, чтобы он вел себя как "существующий" узел, даже если он совершенно новый. Ака..
graph.merge(update_node)
graph.merge(update_node)
Добавление второго вызова слияния позволяет избежать ошибки на данный момент... даже если это немного грязно.
Обновление 2:
Как и просили, вот мои настройки графического ПО
com.graphaware.runtime.enabled=true
com.graphaware.module.UIDM.1=com.graphaware.module.uuid.UuidBootstrapper
com.graphaware.module.UIDM.uuidProperty=uuid
com.graphaware.module.UIDM.stripHyphens=false
com.graphaware.module.UIDM.uuidIndex=uuidIndex
com.graphaware.module.UIDM.uuidRelationshipIndex=uuidRelIndex
Обновление 3: Продолжая отладку, вот результат замены updateUUID просто "uuid", который графическое программное обеспечение свойств обычно создает и присваивает самостоятельно.
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/Flask-0.11.1-py2.7.egg/flask/app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File ".../views.py", line 608, in updateMem
answer = mem.update(results)
File ".../models.py", line 363, in update
graph.merge(update)
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 639, in merge
self.begin(autocommit=True).merge(subgraph, label, *property_keys)
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 1169, in merge
subgraph.__db_merge__(self, primary_label, primary_key)
File "/usr/local/lib/python2.7/dist-packages/py2neo/types.py", line 443, in __db_merge__
tx.run(statement, parameters)
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 1277, in run
self.finish()
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 1296, in finish
self._sync()
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 1286, in _sync
connection.fetch()
File "/usr/local/lib/python2.7/dist-packages/py2neo/packages/neo4j/v1/bolt.py", line 344, in fetch
handler(*fields)
File "/usr/local/lib/python2.7/dist-packages/py2neo/database/__init__.py", line 961, in on_failure
raise GraphError.hydrate(metadata)
ClientError: [Neo.ClientError.Transaction.TransactionHookFailed]