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

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被回滚,但第二个(写日志)应该提交。这似乎可以使用正确的传播级别来写入日志条目: 然而,我的问题是,我在第二个事务中注

    • 我们正试图在spring Kafka消费者中实现事务管理。 我们有Kafka消费者在收听主题A的信息- 我面临的问题是,当数据库事务提交失败时,主题B上的发送操作不会回滚。因此,系统处于不一致状态。 其他场景按预期工作。 例如: > 从kafka读取msg- 阅读Kafka的消息- PS:我知道kafka不支持XA事务。我确实看到一些参考资料提到了ChainedTransactionManager