我有一个与EJB有关的问题以及他们在Glassfish下使用数据库连接的问题,我无法理解为什么我找不到其他人遇到同样的问题,但我所有的搜索都证明是徒劳的。我认为这更像是一个Glassfish,而不是一个Hibernate问题,但希望有人可以在这里提出建议。
我有一个相对简单的设置,它是使用在Glassfish下部署的CMT的基于Hibernate的应用程序。我有几个进入这个应用程序的路径,GUI和WS,都通过EJB调用进入。为了便于在单个事务中运行多个EJB,我在Glassfish连接池中设置了Oracle XADataSource。这一切都运作良好,除了我注意到一件事给我们带来了问题。问题是,通过EJB的任何数据库交互始终与相同的底层连接进行交互(这很好),但是一旦容器接管提交,它就会始终接收不同的连接。任何EJB工作结束时的刷新可以避免任何问题,但是如果任何工作在EJB完成时保持未刷新并且由最终提交处理,则现在在不同(隔离)连接下发生。
对我而言,容器需要与事务的其余部分建立不同的连接似乎很奇怪,但是在Glassfish代码中调试它似乎非常有目的地表现得像这样。在提交时,EJB使用的连接被标记为忙,并且作为空闲资源不可用。这次轮次的分配不是针对交易,所以只是寻找一个免费资源,这将是一个不同的连接。
对于我们来说,这是一个问题,因为我们正在构建一个框架,在这个框架中,无法保证EJB方法中的最后一次调用将是一个刷新。
如果有人能够告诉我这里发生了什么,我将非常感激。我真的不明白为什么对更多人来说这不是一个问题。感谢
使用Glassfish 3.1.1,Hibernate 3.5.6,Oracle驱动程序ojdbc6.jar和javax.sql.XADataSource
答案 0 :(得分:0)
经过Glassfish源代码的大量调试后,我现在对此有了一点了解。 Glassfish中有一个选项可确保发布到CMT提交的连接与整个事务中使用的连接相同。此设置位于连接属性的高级选项卡中,称为“允许非组件呼叫者”。这里的文档http://docs.oracle.com/cd/E26576_01/doc.312/e24930/jdbc.htm#gavro表明第三方持久性管理器会要求这样做,以便'返回的连接自动登记从事务管理器获得的事务上下文'。
我发现这个的原因是我在Glassfish上部署了另一个基于Hibernate的webapp,设置简单得多,而且这次行为不同了,我可以看到数据源名称自动后缀为__pm,这是相同的启用“允许非组件呼叫者”。唯一对我来说仍然是个谜的是为什么我有一个webapp会自动触发这种行为,而另一个则不然。