简体   繁体   中英

Non-Transactional Commands Closes Database in OrienttDB

Within an open transaction the creation of a vertex type, which is non-transactional, closes the database, that was opened before. The following example throws an exception:

public class OrientDBTest {

    public static void main(String[] args) {
        final String url = "plocal:/Users/d022051/tmp/orientdbtest";
        final OrientGraphFactory factory = new OrientGraphFactory(url);
        final OrientGraph graphTx = factory.getTx();
        final ODatabaseDocumentTx documentTx = graphTx.getRawGraph();
        final OrientGraphNoTx graphNoTx = factory.getNoTx();

        graphTx.begin();

        OrientVertexType sequenceClassType = graphNoTx.createVertexType("Sequence");
        sequenceClassType.createProperty("No", OType.LONG).setMin("0").setDefaultValue("0");
        sequenceClassType.createProperty("Name", OType.STRING);

        OSQLSynchQuery<ODocument> selectSequenceCommand = new OSQLSynchQuery<>("select from Sequence where Name = 'GLOBAL'");
        List<ODocument> sequences = documentTx.query(selectSequenceCommand);
        if (sequences.isEmpty()) {
            graphTx.addVertex("class:" + "Sequence", "Name", "GLOBAL");
        }
        graphTx.shutdown();
    }
}

The exception says "the current database is not open on the current thread". Whereas if the graphTx.begin() statement is moved down after the creation of the vertex type, everything is fine. So the graphNoTx command is closing the database for documentTx. I assume the reason is that schema changes cannot be done when a transaction is still open, and thus the transaction is implicitly closed. But, actually the transaction is still open, and a subsequent command using graphTx is successful:

public class OrientDBTest {

    public static void main(String[] args) {
        final String url = "plocal:/Users/d022051/tmp/orientdbtest";
        final OrientGraphFactory factory = new OrientGraphFactory(url);
        final OrientGraph graphTx = factory.getTx();
        final ODatabaseDocumentTx documentTx = graphTx.getRawGraph();
        final OrientGraphNoTx graphNoTx = factory.getNoTx();

        graphTx.begin();

        OrientVertexType sequenceClassType = graphNoTx.createVertexType("Sequence");
        sequenceClassType.createProperty("No", OType.LONG).setMin("0").setDefaultValue("0");
        sequenceClassType.createProperty("Name", OType.STRING);

        graphTx.addVertex("class:" + "Sequence", "Name", "GLOBAL");

        graphTx.shutdown();
    }
}

This runs without error. This looks strange? What is the reason?

@wolf4ood is right. In your code you create transactional graph instance with new database attached to it and make this database active final OrientGraph graphTx = factory.getTx(); then you make active non-tx graph instance with new database instance (not the same as first one) by calling of final OrientGraphNoTx graphNoTx = factory.getNoTx(); but then with active non-tx graph database you try to start transaction on not active database which belongs to tx-instance of graph.

How to avoid this. It is very simple just execute following code before acquiring any graph instance factory.setupPool(5, 15) . This code will create database pool. Pool has following feature - for the same database URL and the same thread the same database instance will be returned (does not matter whether you acquire transactional graph or not).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM