?? ngp.apt
字號(hào):
---------------------------
Next Generation Persistence
---------------------------
~~ Licensed to the Apache Software Foundation (ASF) under one or more
~~ contributor license agreements. See the NOTICE file distributed with
~~ this work for additional information regarding copyright ownership.
~~ The ASF licenses this file to You under the Apache License, Version 2.0
~~ (the "License"); you may not use this file except in compliance with
~~ the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing, software
~~ distributed under the License is distributed on an "AS IS" BASIS,
~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~~ See the License for the specific language governing permissions and
~~ limitations under the License.
Next Generation Persistence
<NOTE: This page describes a proposed persistence model for a future
Jackrabbit core. This is not how Jackrabbit currently works.>
This document describes a radically new persistence model,
"Next Generation Persistence", that is designed to solve some of the
architectural issues that the current Jackrabbit persistence model
introduces (for example the need for synchronization and locking in many
places). The proposed model would also offer many nice features that are
difficult or even impossible to achieve with the current architecture.
There are a number of open questions related to this model, especially
how to make it perform well and to avoid excessive resource usage, but
it is believed that these issues can be solved. The purpose of presenting
this model now is to gather feedback and comments, and to determine whether
it makes sense to continue solving the open issues and to perhaps build
some sort of a prototype start experimenting with the model in practice.
Revision Basics
A JCR workspace is a content tree that consists of two kinds of items,
nodes and properties. This content tree typically changes by time as
items are added, modified, and removed. This model uses a sequence of
revisions to manage these dynamic state changes. A new revision is created
for each state change, and the current state of a workspace is expressed
as the sequence of persisted revisions. A persisted revision is never
modified.
* Initial Revision
The initial revision contains just an empty root node. The root node
can never be removed, but it can of course be modified in later revisions.
----
Session session = ...;
Node root = session.getRootNode();
----
In this case the JCR view of the content would be identical to the
contents of the revision.
[ngp/rev0.jpg] Initial revision
* Adding Nodes
Adding a node results in a revision that contains the added node and
a modification to the parent node. The following code would create a
revision that modifies the root node and adds a single new node called A:
----
Node a = root.addNode("A");
session.save();
----
The resulting revision would look like this:
[ngp/rev1.jpg] First node added
A revision is linked to the previous revision to indicate where to look
for content that was not modified in that revision.
Adding another node to the same parent creates a new revision:
----
Node b = root.addNode("B");
session.save();
----
Now the workspace already contains three revisions:
[ngp/rev2.jpg] Second node added
More than one node can be added in a single revision:
----
Node c = b.addNode("C");
Node d = b.addNode("D");
session.save();
----
In this case the revision would contain the modified parent node and
the two new nodes:
[ngp/rev3.jpg] Two new nodes added
* Removing nodes
Removing nodes is similar to adding them.
----
d.remove();
session.save();
----
A revision that removes a single leaf node contains the modified parent
node and a <removed> marker for the removed node.
[ngp/rev4.jpg] Leaf node removed
The only difference in removing non-leaf nodes, is that now all the nodes
in the removed subtrees are marked as removed.
----
b.remove();
session.save();
----
The resulting revision looks like this:
[ngp/rev5.jpg] Subtree removed
* Handling properties and values
Properties are handled just like leaf nodes. Property values are stored
as a part of the revision where they are introduced. In fact the JCR
value factory can use the revision also to store any large binaries or
other created values that should not be kept in memory. This way an
operation like the following only needs to make a single copy of the value:
----
Property property = ...;
InputStream stream = ...;
Value value = session.getValueFactory().createValue(stream);
property.setValue(value);
session.save();
----
* Multiple operations per revision
A single revision can contain any number of item operations and is not
restricted to just a single subtree at a time. A revision can for example
remove one subtree, add another, and modify the properties in a third one.
This would produce a revision that contains entries for all the modifed
subtrees.
* Revision scope
The revision model described above can be used to manage any content tree,
and a straightforward application in JCR would be to manage each workspace
as a sequence of revisions. This approach has benefits in explicitly
enforcing separation across workspaces and making each workspace separately
manageable for backups and other similar operations described below.
However, there are some cross-workspace operations like versioning and
node type and namespace administration that would become much easier if
the revisions model would in fact cover the entire repository and include
also all the versioning, node type, namespace, and other global content
and metadata. Such an approach would have a repository root node under
which the global <<<jcr:system>>> tree would be kept and which could have
the root nodes of the individual workspaces as normal subnodes.
It is not clear which scope, workspace or repository, would be better in
practice.
Sessions
Each JCR session is associated with two revisions, a <base revision> and
a <draft revision>. The revision model is also used for transaction support.
[ngp/session.jpg] The base and draft revisions
* Base Revision
The base revision of a JCR session is the latest persisted revision that
was available when the session was started. The session uses this revision
as the basis for providing the <JCR view> of the content tree. The base
revision of a session can optionally be changed when more recent revisions
are persisted during the session lifetime. These base revision updates can
happen automatically if the session always wants to see the latest
content, or the base revision can remain constant until the session is
explicitly refreshed.
[ngp/refresh.jpg] Session refresh
The explicit refresh option is beneficial for many JCR clients as they do
not need to worry about the underlying content tree unexpectedly changing
while they are accessing it.
* Draft Revision
The draft revision of a JCR session is the place where all transient
changes are stored. The draft revision always uses the base revision
as the previous revision against which all changes are made. If the
base revision of a session is changed either automatically or because
of an explicit refresh, then the draft revision is updated accordingly.
Draft revisions are the only kinds of revisions that can be modified.
Persisting a draft revision consists of four steps:
[[1]] The previous revision of the draft is updated to the latest
persisted revision of the workspace. Conflicts against revisions
between the session base revision and the latest persisted
revision are detected.
[[2]] Referential integrity of the updated draft revision is checked.
[[3]] Type constraints of the updated draft revision are checked.
[[4]] If no problems were detected, the draft revision is persisted as
the new latest revision of the workspace.
[]
[ngp/save.jpg] Session save
The persisted revision becomes the base revision of the session and a
new draft revision is created.
* Persisting a Subtree
JCR allows a client to persist just a part of the transient space with
the Node.save() method. In this case only changes to that subtree are
persisted. This use case is handled by splitting the draft revision to
two revisions, one with changes to that subtree and one with all the other
changes. The subtree revision is then persisted as described above, and
the session is updated to use the persisted revision as the base revision
and the revision with the remaining changes as the draft revision. If the
operation fails, then the two new revisions are discarded and no changes
are made to the session.
[ngp/subtree.jpg] Node.save()
* Workspace Operations
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -