package com.orientechnologies.orient.core.sql.lock;
import static org.testng.AssertJUnit.assertEquals;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OCommandSQL;
public class TestQueryRecordLockUnlock {
@Test
public void testLockReleaseAfterIncrement() throws InterruptedException {
final ORID id;
ODatabaseDocumentTx db = null;
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.create();
ODocument doc = new ODocument();
doc.field("count", 0);
doc = db.save(doc);
id = doc.getIdentity();
db.commit();
} finally {
if (db != null)
db.close();
}
int thread = 10;
ExecutorService pool = Executors.newFixedThreadPool(thread);
for (int i = 0; i < 10; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
ODatabaseDocumentTx db = null;
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
for (int j = 0; j < 10; j++) {
db.getLocalCache().deleteRecord(id);
String asql = "update " + id.toString() + " INCREMENT count = 1 where count < 50 lock record";
db.command(new OCommandSQL(asql)).execute(id);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
}
});
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
ODocument doc = db.load(id);
assertEquals(50, doc.field("count"));
} finally {
if (db != null) {
db.drop();
}
}
}
@Test(enabled = false)
public void testLockWithSubqueryRecord() throws InterruptedException {
final ORID id;
ODatabaseDocumentTx db = null;
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.create();
ODocument doc = new ODocument();
doc.field("count", 0);
doc = db.save(doc);
id = doc.getIdentity();
db.commit();
} finally {
if (db != null)
db.close();
}
int thread = 10;
ExecutorService pool = Executors.newFixedThreadPool(thread);
for (int i = 0; i < 10; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
ODatabaseDocumentTx db = null;
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
for (int j = 0; j < 10; j++) {
String asql = "update (select from " + id.toString() + ") INCREMENT count = 1 where count < 50 lock record";
db.command(new OCommandSQL(asql)).execute(id);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
}
});
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
ODocument doc = db.load(id);
assertEquals(50, doc.field("count"));
} finally {
if (db != null) {
db.drop();
}
}
}
@Test
public void testLockReleaseAfterIncrementOpenClose() throws InterruptedException {
final ORID id;
ODatabaseDocumentTx db = null;
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.create();
ODocument doc = new ODocument();
doc.field("count", 0);
doc = db.save(doc);
id = doc.getIdentity();
db.commit();
} finally {
if (db != null)
db.close();
}
int thread = 10;
ExecutorService pool = Executors.newFixedThreadPool(thread);
for (int i = 0; i < 10; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
ODatabaseDocumentTx db = null;
for (int j = 0; j < 10; j++) {
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
String asql = "update " + id.toString() + " INCREMENT count = 1 where count < 50 lock record";
db.command(new OCommandSQL(asql)).execute(id);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
}
}
});
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
try {
db = new ODatabaseDocumentTx("memory:" + TestQueryRecordLockUnlock.class.getSimpleName());
db.open("admin", "admin");
ODocument doc = db.load(id);
assertEquals(50, doc.field("count"));
} finally {
if (db != null) {
db.drop();
}
}
}
}