Welcome to the new Gigaspaces XAP forum. To recover your account, please follow these instructions.

Ask Your Question
0

Updating objects in a space

Hello,

I just have a general architecture question to understand how things are suppose to work with a gigaspaces world. I have an application that I am converting that uses GUIs to modify data. In the past, I would have the GUI manipulate a value object and send it back to the server. The server would get/set all the fields and we would just write the data and the hibernate merge would figure out what changed and what didn't (basically do the right thing). Now we are converting this application (and several of our applications work this way). We thought we could read an object out of the space, have the GUI modify it, and send it back to the server and write it. That way all transactional operations happen on the server and are short in duration. However in a gigaspaces world, this doesn't seem to work because it appears we actually need to take the object out of the space to modify it. Is this correct? My concern is having to manage transactions from a GUI so I really don't want the GUI to have to "take" the object out of the space. This could be very expensive in terms of extremely long running transactions.

Thanks,

Rich

This thread was imported from the previous forum.
For your reference, the original is available here

asked 2011-06-22 08:03:06 -0500

rchristy gravatar image

updated 2013-08-08 09:52:00 -0500

jaissefsfex gravatar image
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

Rich,
A write operation with an ID for an object within the space with the same ID will be translated to an update operation implicitly.
The preserve the data consistency you can lock the object using a transaction (when you read it using an exclusive read mode that is pessimistic locking approach) , or use optimistic locking that use versioning to ensure the latest version of the object has been updated and stored within the space.

Leveraging transactions with GigaSpaces does not impose huge overhead as with other transactional systems such as RDBMS or messaging systems. In fact, even a distributed transactions with GigaSpaces are performing very well (compared to other systems).

Optimistic locking avoid the need to perform transactional read and exclusively lock the object, but it comes with a cost: if you don't have the latest version, you will need to read the latest version again and retry and update procedure. I would recommend using pessimistic locking (transactional exclusive read) unless your business logic performs mosly read operations and few updates. The GigaSpace.readById operations is very useful in such cases.

The Transactional behavior is implicit. Just have the relevant spring anotations on the relevant methods/classes. Spring (and GigaSpaces) will take care all the rest.

Note you can speed up write operations by using the NORETURNVALUE Modifier. This will avoid getting the latest version of the object back when performing updates.

See more:
http://www.gigaspaces.com/wiki/display/XAP8/PessimisticLocking
http://www.gigaspaces.com/wiki/display/XAP8/OptimisticLocking
http://www.gigaspaces.com/wiki/display/XAP8/TheGigaSpaceInterface#TheGigaSpaceInterface-writeOperation
http://www.gigaspaces.com/wiki/display/XAP8/TransactionManagement

Shay

answered 2011-06-22 09:47:32 -0500

shay hassidim gravatar image
edit flag offensive delete link more

Comments

I think I might be doing something wrong. The initial write works fine. I than read the object out of the space and try to update it. When I do the write, I am getting a DuplicateIndexValueException saying the object is already in the space and gives me the primary key. I believe (but haven't proven it) it might have something to do with some of the collections I have as child objects. I have a back pointer to the parent and I am wondering if that is the issue. Any help in isolating this issue would be appreciated.

Thanks

Rich

rchristy gravatar imagerchristy ( 2011-06-22 09:56:57 -0500 )edit

As far as I know DuplicateIndexValueException is not a GigaSpaces exception. Any chance you are getting it from the database/Hibernate? Shay

shay hassidim gravatar imageshay hassidim ( 2011-06-22 10:03:40 -0500 )edit

Not exactly sure, but the stack trace is all gigaspaces.

rchristy gravatar imagerchristy ( 2011-06-22 10:13:05 -0500 )edit

can you please post it?

shay hassidim gravatar imageshay hassidim ( 2011-06-22 10:15:34 -0500 )edit

com.skyroad.motion.productmanager.products.ProductException: org.openspaces.core.InternalSpaceException: Entry UID=273261280^61^com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ]^0^0 class=com.skyroad.motion.productmanager.products.NonFungibleProduct value com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ] rejected - an entry with the same UID already in space. otheruid= 273261280^61^com.skyroad.motion.productmanager.products.ProductId@14879f2[ id=1 source=NonFungible ]^0^0; nested exception is com.j_spaces.core.client.DuplicateIndexValueExecption: Entry UID=273261280^61^com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ]^0^0 class=com.skyroad.motion.productmanager.products.NonFungibleProduct value com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ] rejected - an entry with the same UID already in space. otheruid= 273261280^61^com.skyroad.motion.productmanager.products.ProductId@14879f2[ id=1 source=NonFungible ]^0^0 at com.skyroad.motion.productmanager.server.DefaultProductsService.writeProduct(DefaultProductsService.java:51) at com.skyroad.motion.productmanager.products.service.ProductsServiceGigaspacesMethodinternalInvoke0.internalInvoke(Unknown Source) at com.gigaspaces.internal.reflection.fast.AbstractMethod.invoke(AbstractMethod.java:34) at org.openspaces.remoting.SpaceRemotingServiceExporter.invokeExecutor(SpaceRemotingServiceExporter.java:480) at org.openspaces.remoting.ExecutorRemotingTask.execute(ExecutorRemotingTask.java:105) at org.openspaces.remoting.ExecutorRemotingTask.execute(ExecutorRemotingTask.java:47) at org.openspaces.core.executor.internal.InternalSpaceTaskWrapper.execute(InternalSpaceTaskWrapper.java:62) at com.gigaspaces.internal.server.space.SpaceImpl.execute(SpaceImpl.java:640) at com.gigaspaces.internal.server.space.IRemoteSpaceGigaspacesMethodinternalInvoke13.internalInvoke(Unknown Source) at com.gigaspaces.internal.reflection.fast.AbstractMethod.invoke(AbstractMethod.java:34) at com.gigaspaces.lrmi.LRMIRuntime.invoked(LRMIRuntime.java:396) at com.gigaspaces.lrmi.nio.Pivot.consumeAndHandleRequest(Pivot.java:451) at com.gigaspaces.lrmi.nio.Pivot.handleRequest(Pivot.java:545) at com.gigaspaces.lrmi.nio.Pivot$ChannelEntryTask.run(Pivot.java:172) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: org.openspaces.core.InternalSpaceException: Entry UID=273261280^61^com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ]^0^0 class=com.skyroad.motion.productmanager.products.NonFungibleProduct value com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ] rejected - an entry with the same UID already in space. otheruid= 273261280^61^com.skyroad.motion.productmanager.products.ProductId@14879f2[ id=1 source=NonFungible ]^0^0; nested exception is com.j_spaces.core.client.DuplicateIndexValueExecption: Entry UID=273261280^61^com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ]^0^0 class=com.skyroad.motion.productmanager.products.NonFungibleProduct value com.skyroad.motion.productmanager.products.ProductId@1e9262d[ id=1 source=NonFungible ] rejected - an entry with the same UID already in space. otheruid= 273261280^61^com.skyroad.motion.productmanager.products.ProductId@14879f2[ id=1 source=NonFungible ]^0^0 at org.openspaces.core.exception.DefaultExceptionTranslator.internalTranslate(DefaultExceptionTranslator.java:99) at org.openspaces.core.exception.DefaultExceptionTranslator.translate(DefaultExceptionTranslator.java:49 ...(more)

rchristy gravatar imagerchristy ( 2011-06-22 10:19:17 -0500 )edit
0

Ok, it seems to be related to the composite key. I have a simple object model that has a base class with the composite key and one derived class. Any updates to this object structure causes that error. I removed the composite key and use just a Long instead, all works well. Seems that is where the issue is and it does seem to be a gigaspaces issue as far as I can tell from the stack trace.

Edited by: Rich Christy on Jun 22, 2011 11:10 AM

answered 2011-06-22 11:10:39 -0500

rchristy gravatar image
edit flag offensive delete link more

Comments

shay hassidim gravatar imageshay hassidim ( 2011-06-22 11:19:29 -0500 )edit

How is this any different from what I am doing with an embedded compound key - they seem to be the same to me unless I am missing something

http://www.gigaspaces.com/wiki/displa...

The key I am currently using is as follows

package com.skyroad.motion.productmanager.products;

import java.io.Serializable;

import javax.persistence.Column; import javax.persistence.Embeddable;

import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle;

@Embeddable public class ProductId implements Serializable {

private static final long serialVersionUID = 5879984067541319875L;

@Column(name="ID")
public Long   id;

@Column(name="SOURCE")
public String source;

public ProductId() {
}

public ProductId(String source, Long id) {
    this.source = source;
    this.id = id;
}

public String getSource() {
    return source;
}

public void setSource(String source) {
    this.source = source;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((source == null) ? 0 : source.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    ProductId other = (ProductId) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (source == null) {
        if (other.source != null)
            return false;
    } else if (!source.equals(other.source))
        return false;
    return true;
}


public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}

}

rchristy gravatar imagerchristy ( 2011-06-22 11:38:37 -0500 )edit

Ok, after a day of digging through this I figured out the problem. Shay if you take the example of the CompoundId you sent me and add and implement a toString() method as I do below, your example code fails the same as mine. Once I removed this method, the problem went away. I have no idea why implementing toString forces this issue, but I can easily reproduce it

public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
rchristy gravatar imagerchristy ( 2011-06-22 15:43:09 -0500 )edit

Rich, The Compound ID class must implement a toString method that return a unique String for each ID. We have updated the doc to include this info. That's why my example works. I have this:

{code} public String toString() { return key1+ "_" + key2+ "_" + key3; } {code}

Shay

shay hassidim gravatar imageshay hassidim ( 2011-06-23 08:53:37 -0500 )edit

Got it, I changed my toString implementation and it seems to work

Thanks

Rich

rchristy gravatar imagerchristy ( 2011-06-23 09:01:23 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2011-06-22 08:03:06 -0500

Seen: 2,244 times

Last updated: Jun 22 '11