Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LOCK not released in SQL UPDATE SET WHERE LOCK RECORD #2866

Closed
LonelyyHu opened this issue Oct 1, 2014 · 2 comments
Closed

LOCK not released in SQL UPDATE SET WHERE LOCK RECORD #2866

LonelyyHu opened this issue Oct 1, 2014 · 2 comments
Assignees
Milestone

Comments

@LonelyyHu
Copy link

I am trying use SQL command to update record in muti-thread enviroment
it works fine when sql doesn't contain statement "where condition"
ex:
update #10:0 INCREMENT count = 1 lock record
update #10:0 set count = 1 lock record

but if I use statement "where" in SQL, the first thread run succeed, but it didn't release the lock for the record,
then the other threads hung until OLockException been throw
ex:
update #10:0 SET count = 100 where count < 50 lock record
update #10:0 INCREMENT count = 1 where count < 50 lock record

test code:

public static void main(String... args) {

    int thread = 10;

    ExecutorService pool = Executors.newFixedThreadPool(thread);

    for (int i = 0; i < thread; i++) {
        pool.submit(new Runnable() {

            @Override
            public void run() {
                for (int j = 0; j < 10; j++) {
                    ODatabaseDocumentTx db = null;
                    try{
                        db = ODatabaseDocumentPool.global().acquire("remote:localhost/GameDB", "admin", "admin");
                        String asql = "update #10:0 INCREMENT count = 1 where count < 50 lock record";
                        db.command(new OCommandSQL(asql)).execute();
                    }catch (Exception e) {
                        e.printStackTrace();
                    }finally{
                        if(db!=null){
                            db.close();
                        }
                    }                       
                }
                System.out.println(Thread.currentThread().getName() + " done.");
            }
        });
    }

}

Exception:

Caused by: com.orientechnologies.common.concur.lock.OLockException: Timeout (30000ms) on acquiring resource '#10:0' because is locked from another thread
at com.orientechnologies.common.concur.lock.OLockManager.acquireLock(OLockManager.java:104)
at com.orientechnologies.common.concur.lock.OLockManager.acquireLock(OLockManager.java:71)
at com.orientechnologies.orient.core.storage.OStorageEmbedded.acquireWriteLock(OStorageEmbedded.java:187)
at com.orientechnologies.orient.core.tx.OTransactionAbstract.lockRecord(OTransactionAbstract.java:100)
at com.orientechnologies.orient.core.id.ORecordId.lock(ORecordId.java:266)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.readRecord(OLocalPaginatedStorage.java:1486)
at com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.readRecord(OLocalPaginatedStorage.java:753)
at com.orientechnologies.orient.core.db.raw.ODatabaseRaw.read(ODatabaseRaw.java:250)
... 23 more


database: plocal document
I test on Ver-1.7.8, Ver-1.7.9, Ver-2.0 M2, all have the issue,
by the way, I think this issue is the same with issue #2088

@andrii0lomakin
Copy link
Member

the same problem in #2840

@tglman tglman closed this as completed Oct 10, 2014
@lvca lvca removed the In Progress label Oct 14, 2014
tglman added a commit that referenced this issue Oct 14, 2014
…2866

Conflicts:
	core/src/main/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLSelect.java
tglman added a commit that referenced this issue Oct 14, 2014
Conflicts:
	core/src/main/java/com/orientechnologies/orient/core/sql/OCommandExecutorSQLSelect.java
@lvca lvca modified the milestones: 2.0 Final, 2.0-M3 Nov 13, 2014
@theheapdump
Copy link
Contributor

In a distributed environment running on localhost , with three instances of dserver up and running . i get this exception

Apr 02, 2015 2:10:17 PM com.orientechnologies.common.log.OLogManager log
INFO: OrientDB auto-config DISKCACHE=894MB (heap=841MB os=3,783MB disk=395,475MB)
Exception in thread "myThread - 1" Exception in thread "myThread - 2" Exception in thread "myThread - 0" com.orientechnologies.orient.server.distributed.ODistributedException: Error on execution distributed COMMAND
at com.orientechnologies.orient.server.distributed.ODistributedStorage.command(ODistributedStorage.java:397)
at com.orientechnologies.orient.core.command.OCommandRequestTextAbstract.execute(OCommandRequestTextAbstract.java:63)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.command(ONetworkProtocolBinary.java:1178)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.executeRequest(ONetworkProtocolBinary.java:385)
at com.orientechnologies.orient.server.network.protocol.binary.OBinaryNetworkProtocolAbstract.execute(OBinaryNetworkProtocolAbstract.java:220)
at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69)
...............
Caused by: com.orientechnologies.common.concur.lock.OLockException: Cannot unlock a never acquired lock
at com.orientechnologies.orient.core.tx.OTransactionAbstract.unlockRecord(OTransactionAbstract.java:137)
at com.orientechnologies.orient.core.record.ORecordAbstract.unlock(ORecordAbstract.java:305)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.executeSearchRecord(OCommandExecutorSQLSelect.java:519)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.fetchFromTarget(OCommandExecutorSQLSelect.java:1315)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.executeSearch(OCommandExecutorSQLSelect.java:433)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.execute(OCommandExecutorSQLSelect.java:391)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate.execute(OCommandExecutorSQLDelegate.java:64)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.executeCommand(OAbstractPaginatedStorage.java:1189)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.command(OAbstractPaginatedStorage.java:1178)
at com.orientechnologies.orient.server.distributed.ODistributedStorage.command(ODistributedStorage.java:213)
at com.orientechnologies.orient.core.sql.query.OSQLQuery.run(OSQLQuery.java:71)

.................................................................

at com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin.executeOnLocalNode(OHazelcastPlugin.java:757)
at com.orientechnologies.orient.server.hazelcast.ODistributedWorker.onMessage(ODistributedWorker.java:300)
at com.orientechnologies.orient.server.hazelcast.ODistributedWorker.run(ODistributedWorker.java:121)

My Code :

package com.anmol.sequencer;

import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;

public class Mymain {

public static OrientGraphFactory getGraph() {
    OrientGraphFactory factory = new 
            OrientGraphFactory("remote:localhost/anmol" ,
            "root" , "handl3bar").setupPool(1,10);
    return factory;
}


public static void main(String args[]) {
    OSequenceHelper oh = new OSequenceHelper();
    OrientGraphFactory factory = getGraph();
    OrientGraph ogh = factory.getTx();
    oh.getRecordID(ogh, "Test");
    ogh.shutdown();
    myClient myseq[] = new myClient[3];
    for(int i=0;i<myseq.length;i++) {
        String name = "myThread - " + i ;
        myseq[i] = new myClient(name , oh , factory , oh.getRecordID());
        myseq[i].execute();
    }
}

}

package com.anmol.sequencer;

import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientGraphFactory;

public class myClient extends Thread {

private Thread t;
private String threadName;
OSequenceHelper oHelper;
OrientGraph ograph;
private OrientGraphFactory factory;
private String rid;

public myClient(String name, OSequenceHelper oh , OrientGraphFactory og , String recid) {
    threadName = name;
    oHelper = oh;
    factory = og;
    rid = recid;
}

public void execute() {
    t = new Thread(this , threadName);
    t.start();
}
@Override
public void run() {
    ograph = factory.getTx();
    int seq = oHelper.next(rid , ograph , "Test");
    System.out.println("Running " + t.getName() + " - getting sequenceID " + seq );
    ograph.shutdown();
}

}

package com.anmol.sequencer;

import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.tinkerpop.blueprints.impls.orient.OrientBaseGraph;
import com.tinkerpop.blueprints.impls.orient.OrientElement;

public class OSequenceHelper {

    private String recordID;

public void getRecordID(OrientBaseGraph graph , String colass) {
    String query = String.format("select  from osequence where classname = '%s'" , colass);
    Iterable<OrientElement> iterable = graph.command(new OCommandSQL(query)).execute();
    String rec = iterable.iterator().next().getRecord().getIdentity().toString();
    setRecordID(rec);
}

public int next(String recordID , OrientBaseGraph graph, String klass) {
    String query = String.format(
        "update %s increment value = 1 RETURN after @this lock record" , recordID);
    Iterable<OrientElement> iterable = graph.command(new OCommandSQL(query)).execute();
    return iterable.iterator().next().getProperty("value");
}
public String getRecordID() {
    return recordID;
}
public void setRecordID(String recordID) {
    this.recordID = recordID;
}

}

NEED TO FIX THIS URGENTLY -- any help appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants