防止每次读取时发生 DataNucleus 事务

Prevent DataNucleus transactions on every read

是否可以在不创建事务的情况下在 Datanucleus 中读取查询? 我想在我的应用程序中进行非阻塞脏读,但即使不创建事务,我也会在 postgre 日志中看到它。将 属性 "datanucleus.NontransactionalRead" 设置为 true 没有帮助。

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

这是postgre的一部分sql-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

也许这只是一个误会,或者我没有正确表述我的问题。

我深入研究了 postgresql 驱动程序库,我发现在几次 DataNucleus 调用之后,控制转到 HikariProxyPreparedStatement,然后转到 PostgresqlExecutorImpl。有一个 QueryExecutorImpl.sendQueryPreamble() 调用,它以 beginTransactionQuery 作为参数调用 sendOneQuery()。所以 beginTransactionQuery 它是一个只有 "BEGIN" sql 字符串的简单查询。我假设这是一个交易开始。

我说的对吗?如果是这样,如何避免创建交易?如果不对请指正。

我想我已经找到原因了。

DataNucleus 运行事务中的所有查询,但具有 TransactionIsolation.NONE 的查询除外,即使未创建事务也是如此。非事务查询的任何连接都将切换为自动提交 true,并且大多数情况下对于所有其他级别,它将切换为 false。任何类型的 autocmmit true 查询都会导致发送开始事务的 BEGIN 查询。

所以看起来不可能在不进行交易的情况下从 PostgreSQL 读取数据,因为 PostgreSQL 不支持 TransactionIsolation.NONE。如果看一下 ConnectionFactoryImpl

的代码,您可以弄清楚

如果 DataNucleus 开发人员能澄清这一点,那就太好了。