Search code examples
javadatabasepostgresqlconfigurationdatanucleus

Prevent DataNucleus transactions on every read


Is it possible to have read queries in Datanucleus without creating transactions? I would like to have non-blocking dirty read in my application but even without creating transactions I see it in postgre logs. Setting property "datanucleus.NontransactionalRead" to true doesn't help.

entityManager = entityManagerFactory.createEntityManager(); 
Query query = entityManager.createNativeQuery("select * from managers where department_id='1' and account_id = '1'", User.class); 
entityManager.close();

Here is a part of postgresql-9.5-main.log

2018-12-13 14:43:42 user@test LOG: execute <unnamed>: SHOW TRANSACTION ISOLATION LEVEL 
2018-12-13 14:43:42 user@test LOG: execute <unnamed>: BEGIN 2018-12-13 14:43:42 user@test LOG: execute <unnamed>: select * from managers where department_id='9' and account_id = '9' 
2018-12-13 14:43:42 user@test LOG: execute S_2: COMMIT

Maybe it is just a misunderstanding or I haven't formulated my question properly.

I have dug into postgresql driver library I see that after few DataNucleus calls control goes to HikariProxyPreparedStatement and then to PostgresqlExecutorImpl. There is a call of QueryExecutorImpl.sendQueryPreamble() which calls sendOneQuery() with beginTransactionQuery as a parameter. So beginTransactionQuery it is a SimpleQuery with just "BEGIN" sql string. I assume that it is a transaction opening.

Am I right? If so, how to avoid transaction creation? If not please correct me.


Solution

  • I think I have found what is the case.

    DataNucleus runs all queries in transactions except queries which have TransactionIsolation.NONE even if a transaction is not created. Any connection for a non-transaction query will be switched to autocommit true and mostly for all other levels, it will be switched to false. Any kind of autocmmit true query leads to sending BEGIN query which starts a transaction.

    So it looks like it is impossible to do reads from PostgreSQL without making transactions which will be created in any case because PostgreSQL doesn’t support TransactionIsolation.NONE. You can figure it out if take a look on the code of ConnectionFactoryImpl

    It would be nice if somebody from DataNucleus developers clarifies that.