blob: abb7cc633503ed00650b7fb937d1ccead9483fa4 [file] [log] [blame]
---
title: Copy on Read Behavior
---
<!--
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.
-->
Methods that do a get type of operation
receive as a return value a direct reference to the cached object.
This provides the value as quickly as possible,
but it also makes possible code implementations that
could incorrectly modify the referenced object,
bypassing the distribution framework and causing region entries that
are no longer consistent across cluster members.
The code that has the potential for harming cache consistency by using
a reference to access and change a region entry
is code that executes within the servers.
Examples are cache writers and listeners, transactions, and functions.
A client invocation of a get type of operation that is handled by
the servers is not subject to this potential for harm,
as the clients are in a distinct JVM from the servers,
and references do not cross JVM boundaries.
That client cannot receive a return value that is a direct reference
to a region entry, as the servers hold the region entries and the servers
do not reside within the client JVM.
To avoid modification of the referenced object,
create a copy in one of two ways:
- Change the entry retrieval behavior for your cache by setting
the `copy-on-read` cache attribute to true;
its default value is false.
When `copy-on-read` is true,
all entry access methods return copies of the entries.
This protects all server-side code from inadvertently modifying in-place.
This attribute will negatively impact performance and memory consumption
when a copy is not needed,
as it takes time and memory to create the copy.
Note that the `copy-on-read` attribute is applied at the cache level;
it cannot be set for individual regions.
There are two ways to set the `copy-on-read` attribute:
- Set the attribute in the `cache.xml` file that defines the cache.
``` pre
<cache copy-on-read="true">
...
</cache>
```
- Use [`gfsh alter runtime`](../../tools_modules/gfsh/command-pages/alter.html#topic_7E6B7E1B972D4F418CB45354D1089C2B) to set the `copy-on-read` attribute
once the servers have been started.
- Implement server-side code that creates and uses a copy of
the returned object.
For objects that are cloneable or serializable, copy the entry value to a new object using `org.apache.geode.CopyHelper.copy`. Example:
``` pre
Object o = region.get(key);
StringBuffer s = (StringBuffer) CopyHelper.copy(o);
// further operations on the region entry value will use s
s.toUpperCase();
```
Always use a `Region` method to then change data in the region.
Do not use the reference returned from the entry access method.
If the upper case string should become the new value for the region entry:
``` pre
region.put(key, s);
```