Oracle 12c结果集缓存引发Java Web Service数据未更新问题
嘿,我之前用JDeveloper开发Oracle相关Web Service时也碰到过一模一样的问题——删了库中数据后接口返回还是旧值,TotalReq始终不变。大概率是这几个原因导致的,给你逐一排查的方向:
确认手动删除后的事务提交
Oracle默认是手动提交事务的,如果你执行delete from table_name where condition后没有执行commit;,那Web Service用的数据库连接还会读取到事务未提交前的旧数据。先手动执行commit语句,再调用Web Service试试,看TotalReq是不是更新了。检查应用级缓存逻辑
看看你读取数据库的方法里,是不是把查询结果(比如TotalReq的值)存在了静态变量、单例对象或者JDeveloper自带的缓存组件里?如果是这样,第一次查询后结果就被缓存起来,后续请求不会再去数据库拉新数据。可以在方法里加个日志,打印每次请求的查询时间,或者直接在查询语句里加个无意义的动态条件(比如select count(*) as TotalReq from table_name where ... and sysdate = sysdate)来强制每次都走数据库查询。排查连接池的事务隔离与连接重置
JDeveloper的数据库连接池可能会重用旧连接,如果之前的连接没有正确清理事务状态,就会读到旧数据。你可以去连接池配置里看看:- 事务隔离级别是不是设置成了
READ_UNCOMMITTED或者REPEATABLE_READ?Oracle默认的READ_COMMITTED应该能读到已提交的最新数据,但如果配置错了就会有问题。 - 有没有开启连接池的连接重置选项?比如每次重用连接时自动执行
rollback来清除未提交的事务。
- 事务隔离级别是不是设置成了
确认查询的是基表而非物化视图
要是你的查询语句指向的是物化视图(Materialized View),而不是实际的业务表,那物化视图不会自动同步基表的删除操作,需要手动刷新或者配置定时刷新。可以检查一下查询的表名是不是物化视图,是的话执行DBMS_MVIEW.REFRESH('你的物化视图名')刷新后再测试。
如果还是没解决,建议在读取数据的方法里直接打印完整的SQL执行日志,看看每次请求是不是真的执行了查询,以及返回的结果是不是数据库里的最新值。
内容的提问来源于stack exchange,提问作者Mohammed al-kahtani

