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

Ask Your Question
0

Duplicate object written successfully

Hello All,

We have a following SpaceClass which we use as a synchronization token. The idea is that multiple servers may try to write the object of this class with the same SpaceId but only one of the server will succeed. The server which succeeds in write operation will be able to carry out the actual work, other servers will refrain from doing the work. The premise here is that one server will successfully write the object to the spaces and other server will face 'EntryAlreadyInSpaceException'. Our problem arises when two servers write this object successfully to spaces and hence both of them process the work.

Do you think something is wrong with this class? Is our premise wrong in some sense? The time difference between successful write operations by two different servers is usually in milliseconds. Here are the details of our environment.

Gigaspace version: XAP 7.1.1 Mode: partitioned-sync2backup Java Version: 6

{code:java} import java.io.Serializable; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceId; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceRouting; import com.gigaspaces.annotation.pojo.SpaceVersion; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType;

/** *

* This class is used as synchronization mechanism. *

*/ @SpaceClass(replicate = true, persist = false, fifo = false) public class Token implements Serializable{

private static final long serialVersionUID = 1L;
private String messageID;
private int versionID;
private Long timestamp;

public Token() {
}

public Token(String messageID) {
    this.messageID = messageID;
}

@SpaceRouting
@SpaceId(autoGenerate=false)
@SpaceProperty(index = IndexType.BASIC)
public String getMessageID() {
    return messageID;
}

public void setMessageID(String messageID) {
    this.messageID = messageID;
}

public void setVersionID(int versionID) {
    this.versionID = versionID;
}

@SpaceVersion
public int getVersionID() {
    return versionID;
}

public void setTimeStamp(Long timestamp) {
    this.timestamp = timestamp;
}

public Long getTimeStamp() {
    return this.timestamp;
}

public String toString() {
    return StringUtils.append("Token [messageID=" , messageID , ", timestamp=" , timestamp , ", versionID=" , versionID , "]");
}

}

{code}

The code which writes this object to spaces is as followed. {code:java} public static boolean writeToken(String msgID, long leaseTimeout) {

    boolean tokenCreated = false;
    IJSpace space = // get space here
    MessageSynchronizingToken token = new MessageSynchronizingToken(msgID);
    try {
        Object read = space.readIfExists(token, null, 100L);
        // If object already exists then we should not handle this message
        if (read == null) {
            Log.log("Synchronizer: did not find token with id " + msgID);
            token.setTimeStamp(System.currentTimeMillis());
            space.write(token, null, leaseTimeout, 0, UpdateModifiers.WRITE_ONLY);
            Log.log("Synchronizer: successfully wrote token with id " + msgID);
            tokenCreated = true;
        }
    }
    catch (Exception e) {
        Log.log(e.getMessage());                        
    }
    return tokenCreated;

} {code}

{quote}This thread was imported from the previous forum. For your reference, the original is [available here|http://forum.openspaces.org/thread.jspa?threadID=3877]{quote}

asked 2012-06-20 14:49:03 -0600

talkwithsld gravatar image

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

jaissefsfex gravatar image
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

There is a better way to implement "synchronization token" - aka a global lock - See the GigaMap with its lock/unlock API.

If you still want to use the GigaSpace API you should use the Exclusive read Lock as described here:
http://www.gigaspaces.com/wiki/display/XAP9/PessimisticLocking

Note the readIfExists call make more sense only when used with transactions. It does not make lot of sense when the transaction is null.

Anyway , try increasing the write timeout to 1000 ms:

space.write(token, null, leaseTimeout, 1000, UpdateModifiers.WRITE_ONLY);

remove the getVersionID method and the @SpaceVersion since you don't need to run in optimistic locking mode and make sure you actually having the same space ID.

There should not be 2 space objects with the same ID within the space. If you have such behavior please report this to support. I suggest test this also with XAP 9 before reporting this to support.

Shay

answered 2012-06-20 15:38:56 -0600

shay hassidim gravatar image
edit flag offensive delete link more

Comments

Hey Shay,

Thank you for your responses, would you recommentd using the http://www.gigaspaces.com/docs/JavaDoc9.0/org/openspaces/core/GigaMap.html#lock(java.lang.Object, long, long) API? Today we are on 7.1.1 do we have to move to 9 to validate this, has there been implementation upgrades to these APIs.

Thank you
Ramzi

ramzi gravatar imageramzi ( 2012-06-21 11:52:48 -0600 )edit

I suggest you move to XAP 9 as you are using pretty old release. Still , the Lock API should work with 7.1. Shay

shay hassidim gravatar imageshay hassidim ( 2012-06-21 12:35:27 -0600 )edit
0

We added 1000 milliseconds as timeout for both readIfExists and write operations. Since our code release with this change, we have not observed the issue (keeping fingers crossed)

{code:java} Object read = space.readIfExists(token, null, 1000L); // If object already exists then we should not handle this message if (read == null) { Log.log("Synchronizer: did not find token with id " + msgID); token.setTimeStamp(System.currentTimeMillis()); space.write(token, null, leaseTimeout, 1000L, UpdateModifiers.WRITE_ONLY); {code}

Shay, if possible, will you please let us know if there are any side effects of adding timeout (effectively making it a blocking call)?

answered 2012-07-18 12:35:04 -0600

talkwithsld gravatar image
edit flag offensive delete link more

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: 2012-06-20 14:49:03 -0600

Seen: 160 times

Last updated: Jul 18 '12