【问题标题】:J2EE - JPA - EJB3 - Transactions in MDB methodsJ2EE - JPA - EJB3 - MDB 方法中的事务
【发布时间】:2009-10-15 13:15:37
【问题描述】:

我在 JBoss 5.1.0 上部署了资源本地数据源 (Oracle9i):

<datasources>
  <local-tx-datasource>
    <jndi-name>OracleDS</jndi-name>
    <connection-url>jdbc:oracle:thin:@IP_ADDRESS:1521:inv9i</connection-url>
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
    <user-name>***</user-name>
    <password>***</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
    <metadata>
        <type-mapping>Oracle9i</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>

持久化单元:

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="myEJB" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>java:OracleDS</non-jta-data-source>
        <class>hr.bel.model.Instrument</class>
        <class>hr.bel.model.Order</class>
        <class>hr.bel.model.OrderAdditionalData</class>
        <class>hr.bel.model.OrderCondition</class>
        <class>hr.bel.model.Trade</class>
        <class>hr.bel.model.TradeAdditionalData</class>
        <class>hr.bel.model.Tradeticker</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="none" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

在 MDB 中,当调用 onMessage 方法时,我试图持久化一个 bean 并通过 namedQuery 获取该类型的最新 5 个 bean:

@PersistenceContext
    EntityManager em = null;
    public void onMessage(MyMessage msg) {
        Map message = msg.getMessageTree(false);
        Instrument instrument = em.find(Instrument.class, 55);      

        Tradeticker tt = createTradeticker(message);
        tt.setInstrument(instrument);

        log.info("Persisting tradeticker: " + tt.getTradeType());               
        em.persist(tt);             
        log.info("Tradeticker persisted...");

        List<Tradeticker> last5 = em.createNamedQuery("getLast5").setParameter(1,instrument.getInstrumentId()).setMaxResults(5).getResultList();
        log.info("Persisted tradetickers size: " + last5.size());
    }

我的问题是没有任何错误痕迹,但我的 Oracle 数据库中仍然没有任何持久对象。大量消息调用last5.size() 后返回 0。日志非常干净。

我发现对 MDB 的唯一限制是我必须在方法上使用 REQUIRED 或 NOT_SUPPORTED 事务属性。我的 onMessage 没有注释,因此它使用 REQUIRED 作为默认值。另外我在 MDB 类上没有任何注释,所以 bean 应该使用容器管理的事务。

我做错了什么?

【问题讨论】:

    标签: jakarta-ee ejb jboss5.x jta jboss-mdb


    【解决方案1】:

    在使用非 jta 数据源时,您不应该自己管理事务吗?也就是自己获取一个事务并提交数据?我把这类东西留给 JTA 自己,但是当我正确阅读 this 时,看起来在你的情况下你需要明确地提交。

    【讨论】:

    • 是的,你是对的!后来我想...对我来说新的是,如果我管理自己的事务,则不允许使用注入的 EM,而是通过 JNDI 查找调用获得的。显然我应该阅读更多关于 ejb3 的详细信息。
    • Shouldn't you manage the transaction yourself when working with a non-jta data source? 实际上,OP 必须明确提交,因为他使用的是 resource-local 实体管理器,而不是因为 non-jta-datasource(这不太合适虽然因为 MDB + JPA 需要全局事务)。
    【解决方案2】:

    好的。这就是我解决问题的方法,第一次定义 tx 数据源,第二次在 persistence.xml 中定义 jta 模型和 jta-datasource。

    新数据源定义:

    <datasources>
      <xa-datasource>
        <jndi-name>OracleDS</jndi-name>
        <isSameRM-override-value>false</isSameRM-override-value>
        <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
        <xa-datasource-property name="URL">jdbc:oracle:thin:@IP_ADDRESS:1521:inv9i</xa-datasource-property>
        <xa-datasource-property name="User">***</xa-datasource-property>
        <xa-datasource-property name="Password">***</xa-datasource-property>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
        <no-tx-separate-pools/>
        <metadata>
          <type-mapping>Oracle9i</type-mapping>
        </metadata>
      </xa-datasource>
    

    jboss:service=事务管理器

    新的persistence.xml:

    <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
        <persistence-unit name="myEJB" transaction-type="JTA">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <jta-data-source>java:OracleDS</jta-data-source>
            <class>hr.bel.model.Instrument</class>
            <class>hr.bel.model.Order</class>
            <class>hr.bel.model.OrderAdditionalData</class>
            <class>hr.bel.model.OrderCondition</class>
            <class>hr.bel.model.Trade</class>
            <class>hr.bel.model.TradeAdditionalData</class>
            <class>hr.bel.model.Tradeticker</class>
    
            <properties>
                <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/>
                <property name="hibernate.hbm2ddl.auto" value="none" />
                <property name="hibernate.show_sql" value="true" />
            </properties>
        </persistence-unit>
    </persistence>
    

    我的 java 代码是相同的,现在我让我的对象持久化了!在与使用 mysql dbms 的同事讨论后,我们发现 Oracle 及其 tx 和 no-tx 数据源对数据源的使用方式和位置进行了严格限制。 谢谢大家!

    【讨论】:

    • 是的,由于您希望注入实体管理器,因此您必须使用容器管理器实体管理器(必须是 JTA 实体管理器)并提供 jta-data-source
    【解决方案3】:

    顺便说一句:一种常见的模式是将业务逻辑放入 SLSB 并从您的 MDB 中调用它 - 允许逻辑的其他用途。不过应该对您的问题没有影响。

    我希望默认事务属性是必需的。我看不出这会失败的原因。

    我会做这些事情:

    1)。围绕业务逻辑进行尝试/捕捉。是否抛出任何异常?

    2)。删除查询,我看不出它为什么会失败,但让我们删除它可能干扰插入的任何可能性。让我们依靠数据库。在几条消息通过后,使用命令行 SQL 语句或其他实用程序查看数据库中的内容。

    3)。再次查看日志,是不是哪里出现了错误?

    【讨论】:

    • 按照我在解决方案中解释的那样更改描述符后一切正常。无论如何,关于将业务逻辑放入 SLSB,我跳过它,因为客户有重要的性能要求。如何仅从 MDBS 使用 SLSB-s 我跳过了它们,避免了它们周围的所有代理逻辑。如果在运行 ejbs 时有一些关于性能问题的好的链接/文献,那就太好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2011-05-07
    相关资源
    最近更新 更多