【问题标题】:Prevent DataNucleus transactions on every read防止每次读取时发生 DataNucleus 事务
【发布时间】:2018-12-12 12:33:30
【问题描述】:

是否可以在不创建事务的情况下在 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();

这是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

也许这只是一个误解,或者我没有正确地提出我的问题。

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

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

【问题讨论】:

  • NonTransactionRead DEFAULTS 为 TRUE,这只是表示允许没有 JDO 事务的操作。您还没有说在没有 JDO 事务的情况下执行操作(并发布代码)时会发生什么!
  • @BillyFrost 感谢您的回复。这是我在这里的第一个问题,我无法编辑它。 entityManager = entityManagerFactory.createEntityManager(); Query query = entityManager.createNativeQuery("select * from managers where department_id='1' and account_id = '1'", User.class); entityManager.close();
  • 任何 PostgreSQL 日志中都没有显示“事务”......这是一个 JDBC/SQL 连接正在分发和关闭。事务由 JDO/JPA 提供者管理,它将管理正在使用的任何连接。 DataNucleus 日志告诉你它在做什么
  • 我已启用 DataNucleus 日志。你是对的,没有关于开放交易的消息。但我在 postgresql-9.5-main.log 2018-12-13 14:43:42 user@test LOG: execute &lt;unnamed&gt;: SHOW TRANSACTION ISOLATION LEVEL 2018-12-13 14:43:42 user@test LOG: execute &lt;unnamed&gt;: BEGIN 2018-12-13 14:43:42 user@test LOG: execute &lt;unnamed&gt;: select * from managers where department_id='9' and account_id = '9' 2018-12-13 14:43:42 user@test LOG: execute S_2: COMMIT 中看到了
  • 这是一个连接被分配,然后被提交。 EntityManager 通常会使用单个连接,因此您在打开它时得到一个,并在关闭时释放它。

标签: java database postgresql configuration datanucleus


【解决方案1】:

我想我已经找到了情况。

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

所以看起来不可能在不进行任何情况下都会创建的事务的情况下从 PostgreSQL 进行读取,因为 PostgreSQL 不支持 TransactionIsolation.NONE。看ConnectionFactoryImpl的代码就知道了

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2014-03-15
    相关资源
    最近更新 更多