在以下情况中,
Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();
第一个孩子将被保存,但第二个孩子将抛出RepositoryExcepion
,因为节点名称中有斜杠“/”。
现在我想回滚创建两个节点的更改。
如何在JCR / Jacrabbit中处理这个问题?
答案 0 :(得分:1)
Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();
正如您所说,如果行parent.addNode("second/child","nt:unstructured")
引发异常,则不执行s.save()
(永远不会到达该行),而其他人则看不到您对存储库所做的更改。
但是,在您的会话中,firstChild
的添加仍然可见。
您可以刷新会话以放弃会话本地的更改。举个简短的例子:
try {
Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();
} catch (PathNotFoundException ex) {
// log the exception
// give up all unsaved changes made in your session
s.refresh(false);
}
请注意,这只是一个简洁的例子。就个人而言,在尝试保存节点而不是捕获PathNotFoundException
之前,我检查是否存在父节点。关键是,当您想要放弃未保存的更改时,可以执行会话刷新。无论是在catch块还是条件表达式的分支中。
引用Javadoc for Session#refresh(boolean keepChanges)
如果
keepChanges
为false,则此方法会丢弃当前记录在此Session
中的所有待处理更改,并返回所有项目以反映当前保存的状态。在事务之外,此状态只是持久存储的当前状态。在事务中,此状态将反映由已保存但尚未提交的更改修改的持久存储。
至于交易支持,您可以阅读更多here。