当前位置: 首页 > 面试题库 >

“本地事务已具有1个非XA资源:无法添加更多资源”错误

岳佐
2023-03-14
问题内容

阅读有关此错误的先前问题之后,似乎所有这些人都得出结论,您需要在所有数据源上启用XA。但:

  1. 如果我不想进行分布式交易怎么办?如果我想同时在两个不同的数据库上启动事务,但又在一个数据库上提交事务而在另一个数据库上回滚事务,该怎么办?
  2. 我想知道我的代码实际上是如何启动分布式事务的。在我看来,我正在每个数据库上开始完全独立的事务。

有关该应用程序的信息:

该应用程序是在Sun Java Application Server 9.1上运行的EJB。

我使用类似以下spring上下文的内容来设置hibernate会话工厂:

<bean id="dbADatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/dbA"/>
</bean>

<bean id="dbASessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dbADatasource" />
    <property name="hibernateProperties">
        hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
        hibernate.default_schema=schemaA
    </property>
    <property name="mappingResources">
        [mapping resources...]
    </property>
</bean>

<bean id="dbBDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/dbB"/>
</bean>

<bean id="dbBSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dbBDatasource" />
    <property name="hibernateProperties">
        hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
        hibernate.default_schema=schemaB
    </property>
    <property name="mappingResources">
        [mapping resources...]
    </property>
</bean>

这两个JNDI资源都是javax.sql.ConnectionPoolDatasoure的。它们实际上都指向同一个连接池,但是我们有两个不同的JNDI资源,因为将来,这两个完全独立的表组可能会移动到不同的数据库。

然后在代码中,我这样做:

sessionA = dbASessionFactory.openSession();
sessionB = dbBSessionFactory.openSession();
sessionA.beginTransaction();
sessionB.beginTransaction();

sessionB.beginTransaction()行在此帖子的标题中产生错误-
有时。我在两个不同的sun应用程序服务器上运行了该应用程序。一次运行正常,另一次则抛出错误。尽管这两个服务器确实连接到不同但等效的数据库,但在配置方式上没有任何区别。

所以问题是

  1. 上面的代码为什么不开始完全独立的事务?
  2. 如何强制它开始独立事务而不是分布式事务?
  3. 哪种配置可能导致两个应用程序服务器之间的行为不同?

谢谢。

PS堆栈跟踪为:

Local transaction already has 1 non-XA Resource: cannot add more resources. 
at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.enlistResource(J2EETransactionManagerOpt.java:124) 
at com.sun.enterprise.resource.ResourceManagerImpl.registerResource(ResourceManagerImpl.java:144) 
at com.sun.enterprise.resource.ResourceManagerImpl.enlistResource(ResourceManagerImpl.java:102) 
at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:216) 
at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:327) 
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:189) 
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165) 
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:158) 
at com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:108) 
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82) 
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) 
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167) 
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142) 
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85) 
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354) 
at [application code ...]

问题答案:

1上面的代码为什么不开始完全独立的事务?

该应用程序。服务器为您管理交易,如果需要,交易可以是分布式交易。它会自动招募所有参与者。当只有一个参与者时,您不会注意到与普通JDBC事务有什么区别,但是如果有多个参与者,则确实需要分布式事务,因此会出现错误。

2如何强制它开始独立事务而不是分布式事务?

您可以将数据源配置为XA或Local。还可以将Spring /
Hibernate的事务行为配置为使用常规JDBC事务,或将事务管理委托给JTA分布式事务管理器。

我建议您将数据源切换到非XA并尝试将Spring /
Hibernate配置为使用JDBC事务。您应该在文档中找到相关信息,这里我怀疑是要更改的行:

<bean id="txManager" 
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager" />

从本质上讲,这应该意味着您没有在使用该应用程序。服务器分布式事务管理器。

3哪种配置可能导致两个应用程序服务器之间的行为不同?

如果您确实拥有完全相同的应用程序和配置,则意味着在一种情况下,dist中仅招募一名参与者。交易,而第二种情况有两个。一个参与者通常对应一个与数据库的物理连接。可能是在一种情况下,您在两个不同的数据库上使用了两个架构,而在第二种情况下,您在
同一个 物理数据库上使用了两个 架构 吗?一个更可能的解释是,两个应用程序上的数据源配置不同。服务器。 __

PS:如果您使用JTA分布式事务,则应在上使用UserTransaction.{begin,commit,rollback}而不是等效的方法Session



 类似资料:
  • 这是我的应用程序的文件夹结构 在我的文件,我像这样加载字体和资源 对于这个,运行将给出退出代码0。 在我家。dart我有以下课程: 我在其他地方使用,以显示图像(代码省略): 这座大楼没有错误。颤振博士-v没有给出任何错误,颤振分析-v也没有给出任何错误。apk似乎构建得很好,但当应用程序在我的手机上打开时,我在asset_bundle中发现以下错误。投掷: 发生异常。错误(无法加载资源:imag

  • awesome-shell:一份精心组织的命令行工具及资源的列表。 awesome-osx-command-line:一份针对 OS X 命令行的更深入的指南。 Strict mode:为了编写更好的脚本文件。 shellcheck:一个静态 shell 脚本分析工具,本质上是 bash/sh/zsh 的 lint。 Filenames and Pathnames in Shell:有关如何在 s

  • 问题内容: 在Netbeans中,我可以使用现有Java文件源创建一个项目。如果我想向项目添加其他资源,该怎么做? 问题答案: 右键点击项目 “财产” “来源”(在树的左上方) 对话框左侧的“源软件包文件夹:” “新增文件夹”

  • 前面小节我们介绍了如何设置Locale,设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢?这里面的信息包括:文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们将对这些信息一一进行介绍,Go语言中我们把这些格式信息存储在JSON中,然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.jso

  • 问题内容: 我需要JRE使用仅英语版本的JRE资源的翻译版本。 根据ResourceBundle.java文档,这很容易:使用正确的语言环境后缀添加本地化的资源。例如,标准 XMLSchemaMessages.properties 将成为翻译版本: XMLSchemaMessages_FR.properties 等等。 编辑:此特定文件位于:com \ sun \ org \ apache \ x

  • 27.8 更多资源 这章节包含了关于JMX更多的资源链接: Oracle的JMX主页 JMX规范(JSR-000003) JMX远程API规范(JSR-000160) MX4J主页(JMX规范的各种开源实现)