1 回答
TA贡献1874条经验 获得超12个赞
回答您的问题:
1. EJB 方法,用 TransactionAttributeType.REQUIRES_NEW 注释是否会根据 JTA 启动全局 TX?
是的,REQUIRES_NEW 会导致容器启动一个新的全局事务。
2. 我的假设是否正确,即从数据源检索新的 JDBC 连接会根据 JTA 启动新的本地事务?
你几乎是对的。检索 JDBC 连接实际上并不启动事务。但是,在没有全局事务的情况下,对 JDBC 连接(例如 createStatement、execute 等)执行有意义的工作会启动本地事务。
3. 如果以上都是正确的,那么在全局 TX 下是否可以在 EJB 中使用普通 JDBC?或者我应该只从非事务性 EJB 调用与 JDBC 相关的方法?
无论是否在全局事务下,普通 JDBC 对 EJB 都是完全有效的。
4. 我应该认为上述方法是错误的吗?
您描述的场景应该可以正常工作。很可能有一些额外的细节导致了问题,可能与订购或不提交有关。
5. 我应该使用更抽象的 JTA 接口来处理数据库,而不是使用“普通”的 JDBC 方法吗?如果是这样,那么哪种方式更可取?
我建议调试您所看到的问题的原因。
如果我理解你描述的场景,你调用 getConnection 两次,第一次是在一个全局事务中因为 EJB 标记为 REQUIRES_NEW,随后,在该方法返回并且事务提交之后,你第二次调用 getConnection 并使用它是一个新的本地交易。您应该澄清哪个 getConnection 尝试失败,是否还有其他尝试,如果可能,请从您的源代码中发布片段。您还应该发布错误的完整堆栈。缺少这些,这意味着您得到的答案更有可能是猜测而不是答案。例如,考虑到 Oracle 错误,我可以猜测您可能在尝试在全局事务中使用连接之前从未提交的本地事务中额外使用了该连接。还需要注意的是,在应用服务器中,连接被池化,因此先前的使用可能来自未在本地事务中提交连接的不同线程。应用程序服务器会尽最大努力检测此类事件并为您清理,但并非总是如此。因此,对于在某些情况下可能不会提交/回滚的任何连接,您还需要查看其他连接使用情况。
添加回答
举报