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

一起使用Spring和EJB事务

酆耀
2023-03-14
@Remote
public abstract interface DatalayerService{
   public abstract void add(Object object)
}

这是请求

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class DatalayerServiceImpl implements DatalayerService{
  @PersistenceContext(name="myPersistenceUnit")
   EntityManager em = null;

  @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void add(Object object) throws FatalException{
        try {
            em.persist(object);
        }
        catch (Throwable e){
            throw manageDatalayerError(e);
        }
        finally {

        }
    }
}

我试图在我的应用程序中使用上面的ejb

1)

@ComponentScan({"com.springboot"})
@EnableJpaRepositories
@SpringBootApplication
public class SpringEjbApplication extends SpringBootServletInitializer{


    public static void main(String args[]){
        SpringApplication.run(SpringApplication.class,args);
    }



    @Bean
    public DatalayerService datalayerService() throws NamingException{
        return new DatalayerServiceImpl();
    }


    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException{
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[]{"com.springboot.pojo"});
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        em.setJpaVendorAdapter(vendorAdapter);
        em.setPersistenceUnitName("myPersistenceUnit");
        em.setJpaProperties(additionalProperties());
        return em;
    }



    @Bean
    public DataSource dataSource() throws NamingException{
        return (DataSource) new JndiTemplate().lookup("openejb:Resource/MyDataSource");
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }


    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }


    private Properties additionalProperties(){
        Properties properties = new Properties();
        properties.setProperty("hibernate.max_fetch_depth", "3");
        properties.setProperty("hibernate.default_batch_fetch_size", "2");
        properties.setProperty("hibernate.jdbc.batch_size", "100");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "false");
        return properties;
    }
}
@RestController
public class HomeEndPoint{

    @Autowired
    private IUserService iUserService;

    @GetMapping("/createUser")
    @Transactional(rollbackFor = {ServiceExpectedException.class,FatalException.class,MandatoryParameterMissingFatalException.class})
    public void createUser() throws FatalException,ServiceExpectedException{
        iUserService.createUser();
    }

}
public interface IUserService{
   public void createUser() throws FatalException;
}

    @Service
@Transactional(rollbackFor = {ServiceExpectedException.class,FatalException.class,MandatoryParameterMissingFatalException.class})
public class UserServiceImpl implements IUserService{
     @Autowired
    private DatalayerGenericService datalayerGenericService;

     @Override
    public void createUser() throws FatalException,ServiceExpectedException{
     Team team = new Team(simpleContextService);
        team.setGroupName("MyTeam");
        team.setStoreId(100);
        // Team
        datalayerGenericService.add(team);
        Log.info(this,"add team ");
        // Build user1
        datalayerGenericService.add(user1);
        Log.info(this,"############################# Added User1 ######################################");
        // Build user2
        datalayerGenericService.add(user2);
        Log.info(this,"############################# Added User2 ######################################");

}
}
http://localhost:6180/SpringBootDatalayer/createUser

包含JDBC语句2018-03-27 16:28:17,683:错误:http-nio-6180-exec-1:BatchingBatch.PerformExecution:HHH000315:Exception执行批处理[java.sql.BatchUpdateException:batch entry 0 insert into TEAM(CREATE_TIMESTAMP,PROJECT_GROUP_NAME,LAST_UPDATE_TIMESTAMP,STORE_ID,ID)values('2018-3-27 16:28:17.447000+5:30:0‘,'mma_test','2018-3-27 TEAM(CREATE_TIMESTAMP,PROJECT_GROUP_NAME,LAST_UPDATE_TIMESTAMP,STORE_ID,ID)值(?,?,?,?,?)

从异常中可以看到,它使用DataLayerGenericService创建了team、user1和user2。但是试图再次执行以给出AbstractBatchImpl.release:HHH000010:在批处理的发布时,它仍然包含JDBC语句。

下面是我得到的例外:

batchUpdateException:批条目1插入TEAM(CREATE_TIMESTAMP,PROJECT_GROUP_NAME,LAST_UPDATE_TIMESTAMP,STORE_ID,ID)值('2018-3-29 12:9:26.611000+5:30:0‘,'mma_test','2018-3-29 12:9:26.836000+5:30:0’,100,23)被中止。调用getNextException查看原因。

如何解决此问题?为什么查询执行两次?

如果EJB方法中出现任何异常,它应该回滚事务。但这并没有发生

注意:如果我从服务中删除@Transactional注释,它可以正常工作。我使用的是Tomee7.0.2服务器

共有1个答案

郑功
2023-03-14

从技术上讲,您既不插入用户,也不插入团队。您可以将它们持久化到PersistenceContext。当您的代码离开时

@Transactional(rollbackFor = {ServiceExpectedException.class,FatalException.class,MandatoryParameterMissingFatalException.class})
    public void createUser()

它必须被提交、刷新或关闭会话,只要您根据需要标记了它。它在第一次插入(团队)时就失败了,因为你没有上面列出的一些。

是的,您在这里使用的是EJB中的Note。实际上,您使用Hibernate,只有@Transactional作为Spring服务注释在这里有效。

 类似资料:
  • public void A()抛出ApplicationException{ } 这是方法B(): } 显然,如果删除方法B()中的catch块,就不会出现这种行为。现在,我想知道是否有一种方法可以回滚我的事务,即使我捕捉到方法B()中的异常。谢谢!!!!

  • 问题内容: Spring对RDBMS事务管理的支持在Spring WebFlux中是否也起作用? 例如,假设配置正确,带有注释的方法是否会使用Spring事务管理器并在发生错误时回滚事务? 如果事务管理确实起作用,那么方法是否必须实际和异常,或者必须是或返回类型发出错误信号? 我知道JDBC本质上是阻塞的,因此任何JDBC操作都必须从阻塞过渡到反应性,反之亦然。 Spring事务管理器通过使用(对

  • 问题内容: 我在尝试将Hibernate事务中所做的更改推送到数据库以使DbUnit在我的测试用例中正常工作时遇到问题。似乎DbUnit没有看到Hibernate所做的更改,因为它们尚未在事务结束时提交。 这是我过度简化的测试用例,用于演示我的问题:- 我使用DbUnit的整个想法是: 将数据保存到多个表的调用。 使用DbUnit从XML获取期望的表。 使用DbUnit从数据库获取实际表。 做。

  • 我目前正在使用Wink 1.1.1和Spring 3.1.2迁移一个Java应用程序从WAS7到WAS8.5.5。我正在尝试使用Wink 8.5中可用的本地Wink集成,而不是使用我们目前在Wink 7中使用的单独Wink罐。 我得到了一个错误的服务器启动,看起来像这样: 原因:java。lang.ClassNotFoundException:org。阿帕奇。眨眼服务器内部的登记处。java上的R

  • 问题内容: 这篇文章是JPA的延续。如何在持久化后从数据库获取值 当我执行以下命令时,我将遵循以下异常,该如何解决呢? DAOImpl 代码 applicationContext.xml 问题答案: 我猜这里的问题是,尽管您已经为事务管理器定义了bean,但是您没有注释启用弹簧事务的create()方法。 还要删除该语句,因为现在所有事务管理都将在spring之前完成,如果您保留该语句不变,则将再

  • Spring对RDBMS事务管理的支持在Spring WebFlux中也起作用吗? 例如,假设配置正确,用注释注释的方法是否会使用Spring事务管理器并在发生错误时回滚事务? 如果事务管理确实起作用,那么方法是否确实和异常,或者或返回类型是否发出错误信号? 我知道JDBC本质上是阻塞的,因此任何JDBC操作都必须从阻塞桥接到反应桥接,反之亦然。 我的组织有WebFlux和Cassandra的经验