use of de.fhg.igd.mongomvcc.VException in project mongomvcc by igd-geo.
the class MongoDBVBranchTest method createBranchAfterConflict.
/**
* Creates another branch after a conflict has happened
*/
@Test
public void createBranchAfterConflict() {
VBranch master2 = _db.checkout(VConstants.MASTER);
putPerson("Max", 3);
VCollection persons2 = master2.getCollection("persons");
persons2.insert(_factory.createDocument("name", "Elvis"));
long masterCid = _master.commit();
try {
master2.commit();
fail("We expect a VException here since the branch's head " + "could not be updated");
} catch (VException e) {
//this is what we expect here
}
//committing master2 failed, but the commit is still there
long master2Cid = master2.getHead();
assertTrue(masterCid != master2Cid);
_db.createBranch("master2", master2Cid);
VBranch master = _db.checkout(VConstants.MASTER);
assertEquals(masterCid, master.getHead());
master2 = _db.checkout("master2");
assertEquals(master2Cid, master2.getHead());
}
use of de.fhg.igd.mongomvcc.VException in project mongomvcc by igd-geo.
the class MongoDBVCollectionTest method conflict.
/**
* Tests if the database throws an exception if a conflict arises
* @throws Exception if everything works as expected
*/
@Test
public void conflict() throws Exception {
//obtain collection to get a snapshot of the current database
_master.getCollection("persons").find();
assertEquals(0, _master.getCollection("persons").find().size());
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
class ConflictCallable implements Callable<Object> {
@Override
public Object call() throws Exception {
//obtain collection to get a snapshot of the current database
_master.getCollection("persons").find();
assertEquals(0, _master.getCollection("persons").find().size());
latch2.countDown();
try {
latch1.await();
} catch (InterruptedException e) {
fail();
throw new RuntimeException(e);
}
//insert new person and commit
putPerson("Peter", 26);
_master.commit();
assertEquals(1, _master.getCollection("persons").find().size());
return null;
}
}
//let other thread make commit based on the same head
FutureTask<Object> ft1 = new FutureTask<Object>(new ConflictCallable());
Executor exe = Executors.newCachedThreadPool();
exe.execute(ft1);
//wait until other thread has obtained the same branch
while (!latch2.await(100, TimeUnit.MILLISECONDS)) {
//check if the other thread threw an exception meanwhile
if (ft1.isDone()) {
ft1.get();
}
}
//let other thread commit its result
latch1.countDown();
//insert new person and commit
putPerson("Max", 5);
//wait for the other thread to exit
ft1.get();
//should throw here because of a conflict
try {
_master.commit();
} catch (VException e) {
//this is what we expect
return;
}
fail("Should have thrown a VException up to now");
}
use of de.fhg.igd.mongomvcc.VException in project mongomvcc by igd-geo.
the class Tree method addBranch.
/**
* Adds a named branch. Always waits for the database to fsync before
* returning. This guarantees all threads will see the change.
* @param name the branch's name
* @param headCID the CID of the head commit the branch points to
* @throws VException if there already is a branch with the given name or
* if the given head CID could not be resolved to an existing commit
*/
public void addBranch(String name, long headCID) {
//and then we write
synchronized (this) {
//check prerequisites
if (_branches.findOne(name) != null) {
throw new VException("A branch with the name " + name + " already exists");
}
resolveCommit(headCID);
//create branch
DBObject o = new BasicDBObject();
o.put(MongoDBConstants.ID, name);
o.put(MongoDBConstants.CID, headCID);
o.put(ROOT_CID, headCID);
_branches.insert(o, WriteConcern.FSYNC_SAFE);
}
}
Aggregations