当前位置: 首页 > 知识库问答 >
问题:

SPRING、JPA(EclipseLink)和JTA事务管理器(JBoss7)-不提交到数据库

聂昱
2023-03-14

我创建了一个示例--SPRING,JPA(EclipseLink持久性提供程序)和JTA事务管理器(JBoss7)。我观察到数据库中的所有数据都正确地显示在UI中以进行读操作。但是当涉及保存/更新或删除操作时,服务层不将工作提交到数据库。没有捕获到异常(我也检查了控制台/日志,并且调试了代码,可以看到EntityManager.persist/remove被调用,没有任何异常)。

<datasource jta="true" jndi-name="java:/mysql_customerdb3" pool-name="mysql_customerdb3_pool" enabled="true" use-java-context="true" use-ccm="true">
            <connection-url>jdbc:mysql://localhost:3306/customerdb</connection-url>
            <driver>mysql</driver>
            <security>
                <user-name>root</user-name>
                <password>root</password>
            </security>
            <statement>
                <prepared-statement-cache-size>10</prepared-statement-cache-size>
                <share-prepared-statements>true</share-prepared-statements>
            </statement>
        </datasource>
        <drivers>
            <driver name="mysql" module="com.mysql">
                <driver-class>com.mysql.jdbc.Driver</driver-class>
    <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
            </driver>
            <driver name="h2" module="com.h2database.h2">
                <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
            </driver>
        </drivers>

>

  • module.xml中的数据库驱动程序配置

    persistence.xml

    <context:annotation-config />
    <context:component-scan base-package="com.springforbeginners" />
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
        <property name="loadTimeWeaver" ref="loadTimeWeaver" />
        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
    </bean>
    
    <bean id="loadTimeWeaver" class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" >
    </bean>
    
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value="java:jboss/TransactionManager"/>
        <property name="userTransactionName" value="java:jboss/UserTransaction"/>
    </bean> 
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    

    软件包com.springforbeginners.service;

    导入com.springforbeginners.dao.customerdao;导入com.springforbeginners.model.customer;导入java.util.List;导入org.springframework.beans.factory.annotation.autowired;导入org.springframework.stereotype.service;导入org.springframework.transaction.annotation.transactional;

    @Service公共类CustomerServiceImpl实现CustomerService{@Autowired private CustomerDAO CustomerDAO;

    @Transactional
    @Override
    public void addCustomer(Customer customer) {
        customerDAO.addCustomer(customer);
    }
    
    @Transactional
    @Override
    public List<Customer> listCustomer() {
        return customerDAO.listCustomer();
    }
    
    @Transactional
    @Override
    public void removeCustomer(Integer customerId) {
        customerDAO.removeCustomer(customerId);
    }
    

    }

    CustomerDAOImpl.java

    包com.springforbeginners.dao;

    导入com.springforbeginners.model.customer;导入java.util.List;导入javax.persistence.EntityManager;导入javax.persistence.PersistenceContext;导入org.springframework.stereotype.repository;

    @Override
    public void addCustomer(Customer customer) {
        entityManager.persist(customer);
    }
    
    @Override
    public List<Customer> listCustomer() {
        return entityManager.createQuery("select c from Customer c", Customer.class).getResultList();
    }
    
    @Override
    public void removeCustomer(Integer customerId) {
        Customer customer = (Customer) entityManager.getReference(Customer.class, customerId);
        if (null != customer) {
            entityManager.remove(customer);
        }
    }
    

    }

    我不知道到底缺了些什么和什么地方。但是使用上面的代码,读取操作可以按照预期工作。问题是保存操作。我已经将上面的示例转换为使用非JTA数据源(还修改了standalone.xml,用于jta=false),并使用JpaTransactionManager,如下所示

    我将在JBoss上运行这个应用程序。但是JBoss上的一个数据源和Glassfish上的另一个数据源和transaction应该同时跨越两个数据源上的save操作。这就是我正在努力实现的目标。我有一个包含spring for service(data)层的web应用程序目前运行在JBoss上。

    正如您前面所说-我将有两个persistence.xmls,一个用于JBoss,一个用于GlassFish。当我第一次这样做时,我对事务(它跨越不同服务器上的两个数据源--在本例中是JBoss和Glassfish)是否可以完全由JBoss执行(如果整个业务逻辑驻留在部署在JBoss上的serviceImpl类中)表示怀疑?在本例中,我将使用JBoss事务管理器(属性名称=“TransactionManagerName”value=“java:JBoss/TransactionManager”)。这就足够了吗?还是我也需要类似的Glassfish事务管理器?抱歉,如果这造成了混乱。

    我的另一个问题是,在persistence.xml/Anywhere else中是否有指定jndi端口的规定?(我肯定会有两个不同的persistence.xmls,我将在一个中提到目标服务器为JBoss,在另一个中提到目标服务器为Glassfish)。

    我们在spring中是否有一种技术,可以通过它将业务逻辑分布在不同的服务器(如JBoss/GlassFish)上,并且仍然在一个单一的Transatcion下?我不知道这是否是一个选择。您所说的场景是不是需要两个不同的部署脚本,每个服务器一个?

    谢谢普拉卡什

  • 共有1个答案

    郎雪风
    2023-03-14

    您的persistence.xml是什么?

    由于您使用的是JTA,因此必须定义“eclipselink.target-server”=“jboss”

     类似资料:
    • 在我的spring服务中,我调用了两个spring数据存储库方法 现在我的查询与事务管理相关。就我所了解和看到的代码而言,spring存储库使用@Transactional为其方法启用了事务。对于select操作,它的readonly=true。 我对事务的理解是,当执行选择操作时,会创建一个事务,然后为保存操作创建另一个事务,因为对于选择操作,事务只读=true。 我希望在单个事务中执行读写操作

    • 并用@Transactional注释了具体类。 我们使用Jboss应用服务器支持通过JNDI与MQ集成。这里的问题是,如果监听器中的任何层有任何异常,则整个事务不会回滚,消息也不会移动到退出队列。很明显,当我们使用Hibernate事务管理器时,它不知道其他资源,如JMS事务。 我可以安全地用JTA事务替换它吗,因为Jboss将处理整个事务管理?这样做是否有任何可预见的风险?

    • 我在JTA和Wildfly8中使用Eclipselink,问题是在提交用户事务并将数据插入数据库后,它不会更新相关实体,所以如果我重新加载页面或打开页面的新实例,它加载数据时不会插入行。

    • 我正在阅读使用Spring框架的事务管理。在第一个组合中,我使用Spring Hibernate和Hibernate的API来控制事务(Hibernate API)。接下来,我想使用注释进行测试,它确实起了作用。 我感到困惑的是: > JPA、JTA、Hibernate是否有自己的事务管理方式。举个例子,考虑如果我使用Spring Hibernate,在那种情况下,你会使用“JPA”事务吗? 就像

    • 我正在使用Spring的事务支持和JPA(Hibernate)来持久化我的实体。一切正常,但我在处理一个请求中的部分更新时陷入困境: 对于每个用户(HTTP)请求,我必须将一个日志条目写入数据库表,即使“主”业务实体的更新失败(例如,由于验证错误)。因此,我的第一个/主要事务get被回滚,但第二个(写日志)应该提交。这似乎可以使用正确的传播级别来写入日志条目: 然而,我的问题是,我在第二个事务中注

    • 在代码里事务提交后方法结束,此时数据库是否已经执行了事务?因为事务提交返回了成功说明数据库已经处理了这个事务提交,但是此时数据库实际是否已经有执行完成这个事务?还是代码里事务提交完成后数据库实际并没有执行完成,只是先返回了成功的信息?现在碰到一个情况是方法提交结束后另外一个程序立刻调用存储过程查询数据会出现查不到的情况。