【发布时间】:2021-02-18 15:12:48
【问题描述】:
为了连接到我的 Oracle DB,我使用了瘦 Oracle JDBC 驱动程序和 tomcat JDBC 连接池。
tomcat-pool的默认设置是在返回池时不触碰连接(任何关联的事务不提交也不回滚,实际连接不关闭)。
Oracle驱动默认事务隔离级别为READ_COMMITTED,自动提交设置为false
我有几种业务方法使用同一个连接池连接到数据库。在某些业务方法中,我明确地创建一个新事务,发布一些更新并提交该事务。到目前为止一切顺利。
其他一些业务方法是只读的。它们是只读的,因为我只发出SELECT 查询,而不是因为我在连接上明确设置了READ ONLY 模式(它保持关闭)。
我的理解是,在这种情况下,Oracle 第一次遇到SELECT 语句时会创建一个新的隐式事务,并保持该事务处于打开状态,直到我明确地COMMIT 它。
但是,鉴于我只发出SELECT 查询,我觉得没有必要提交事务。
我了解,在将连接返回池之前不提交这些只读事务意味着下次从池中借用连接时,下一个业务方法将在之前已经启动的事务中执行。
我的问题是:
- 重要吗?
- 鉴于事务隔离设置为
READ_COMMITTED并且自动提交设置为false,如果我提交只读事务,是否存在任何潜在的额外数据竞争条件? - 不提交事务是否会在数据库服务器端产生性能成本(事务可能会保持数小时未提交)?
- 如果我们连接到 RAC 而不是单个 Oracle 数据库实例,上述问题的答案是否会改变?
- 如果我从 DB 链接中选择呢?
从我读过的所有资源来看,到目前为止,我的结论是我所做的在技术上是不正确的,但只要我不选择更高的事务隔离级别也没关系。 READ_COMMITTED 将读取其他事务最近提交的任何内容,而不管当前事务是否已提交,并且 Oracle 服务器上用于跟踪没有未决修改的事务的开销是微不足道的。所以修复这个问题属于“应该修复,但不是紧急情况”的范畴。
这是有道理的还是我误解了一些重要的事情?
【问题讨论】:
-
我查看了其中一堆的代码,但默认情况下没有一个是这样做的。有些具有额外的设置,可让您配置自动提交或自动回滚。
-
感谢您的链接。它的相关之处在于它提供了有关如何设置池以自行进行提交的线索。但是,它没有回答我提出的问题。我认为这些问题的答案很有趣,我找不到任何其他资源可以明确回答这些问题。此外,tomcat-pool 可以配置为在返回时提交事务,但它将无条件提交。这意味着在我已经提交 TX 的情况下,我将承担额外的、不必要的 DB 往返来提交空事务。
-
您认为为什么会为
select创建事务?司机是在做自己的set transaction电话吗?否则仅查询数据不应该启动事务。 -
是的,显式启动的事务不会被隐式关闭。我怀疑你会遇到关键问题,但它仍然是一个令人讨厌的不确定性向量。我更担心未来的程序员错误,而不是数据库无法处理未提交的连接。或许您应该考虑一些措施来让开发人员更轻松地处理 tx?手动交易处理繁琐且容易出错。
标签: java oracle jdbc transactions