有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (3) 个答案

  1. # 1 楼答案

    据我所知,您不需要重新启动应用程序,只需重新创建到数据库的连接,这是因为驱动程序在内存中保留了一个与以前编译的包版本的链接,因此新的连接将获得更新版本。这通常是在PLSQL/Oracle数据库上观察到的,它与驱动程序有关,而与Java无关。 看看这个问题/答案,Does Tomcat use cached versions of pl/sql modules?,它有一些如何克服这种情况的建议

    希望有帮助

  2. # 2 楼答案

    Oracle软件包可以包含状态信息。在包体中,可以在包级别定义变量。这些“全局变量”存在于对数据库的调用之间,并与数据库会话相关联。当重新编译包时(我猜这是您在错误中看到的“修改的”),您可以从包体中添加或删除变量,这样Oracle就必须抛弃包的旧状态并创建一个新的。它警告您,它通过引发一个ORA-04068:包的现有状态已被丢弃来实现此目的

    如果您使用某种类型的连接池(包括Database Resident Connection Pooling),这在web服务器上是典型的,那么您需要记住,当您在代码中关闭连接时,连接并没有真正关闭。当应用服务器完成它(通过调用关闭、处置等)时,它刚刚返回池,但它保持打开状态,Oracle数据库没有注意到你认为它是“关闭的”。当需要新连接时,它会从池中获取旧连接并将其提供给服务器。由于Oracle从未关闭连接,因此会话自上次使用以来仍处于活动状态。如果自上次使用连接后,软件包发生了更改,您仍然可以获得一个ORA-04068,即使您的代码看起来您刚刚打开了一个全新的连接。重新启动应用程序服务器将导致池中的所有连接在关闭时关闭,并在启动时重新创建,这似乎就是您现在解决问题的方法

    • 如果您可以这样做,最好的选择是使用edition based redefinition。这样可以编译新包,但只有新会话才会使用新代码。旧会话将继续使用旧代码。同样,如果你在做bug修复之类的事情,这可能不太理想,因为在旧会话取代新会话之后,他们才开始修复

    • 第二种选择是,如果您知道您不关心该特定包的内部状态是否丢失,则只需再次运行包过程/函数调用。Oracle不会再次向您提供ORA-04068(除非重新编译包)

    希望这有帮助。如果没有更多关于你所看到的和你所处环境的确切错误的细节,那将是很有帮助的

  3. # 3 楼答案

    重新编译该包后刷新共享池会有所帮助,因为在共享池刷新后,只要连接的会话第一次尝试访问该包,就会强制它们执行重新解析

    具有DBA权限: 改变系统刷新共享池

    请注意,在刷新共享池之后,其他应用程序可能会经历一段时间的缓慢,因为它们连接的会话也将被迫重新解析它们的SQL/PLSQL语句,因此建议在刷新共享池的同时计划重新编译包