JCR / Jackrabbit的交易是否有任何支持?

时间:2017-01-27 06:04:51

标签: aem jcr jackrabbit

在以下情况中,

Session s = getJcrSessionWithSimpleCredentials();
Node parent = getSomeNode(s).;
parent.addNode("firstChild","nt:unstructured");
parent.addNode("second/child","nt:unstructured");
s.save();

第一个孩子将被保存,但第二个孩子将抛出RepositoryExcepion,因为节点名称中有斜杠“/”。 现在我想回滚创建两个节点的更改。

如何在JCR / Jacrabbit中处理这个问题?

1 个答案:

答案 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