Java Jpa@Transactional donds';t回滚

Java Jpa@Transactional donds';t回滚,java,spring,jpa,transactional,Java,Spring,Jpa,Transactional,更新:该表被设置为MyISAM而不是InnoDB,从而解决了该问题 所以我有这个方法: @Transactional() @Override public List<Order> findAll() { Order order = new Order(); Order order1 = new Order(); Order order2 = new Order(); orderRepository.save(order); orderRepos

更新:该表被设置为MyISAM而不是InnoDB,从而解决了该问题

所以我有这个方法:

@Transactional()
@Override
public List<Order> findAll() {
    Order order = new Order();
    Order order1 = new Order();
    Order order2 = new Order();
    orderRepository.save(order);
    orderRepository.save(order1);
    orderRepository.save(order2);

    return orders;
}
仍然没有回滚。我也试过了

@Transactional(propagation=Propagation.REQUIRED)
@Transactional(rollbackFor = Exception.class)
还是没有什么能像这样假装回滚?通过在方法中抛出异常,如果不是,如何测试回滚?这是我的配置:

@Configuration
@EnableWebMvc
@EnableTransactionManagement
public class AppConfig {


    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em
                = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("com.project.models");

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }
    @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/project");
        dataSource.setUsername( "root" );
        dataSource.setPassword( "1234" );
        return dataSource;
    }
    @Bean
    public PlatformTransactionManager transactionManager(
            EntityManagerFactory emf){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);

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

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty(
                "hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }
使用日志中的某些内容更新:

Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:05 - Creating new EntityManager for shared EntityManager invocation
""2019-02-10 09:30:05 - Closing JPA EntityManager
""2019-02-10 09:30:06 - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
""2019-02-10 09:30:06 - Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1d1cfe4, org.springframework.security.web.context.SecurityContextPersistenceFilter@10745a02, org.springframework.security.web.header.HeaderWriterFilter@3d798e76, org.springframework.web.filter.CorsFilter@ba562e0, org.springframework.security.web.authentication.logout.LogoutFilter@13c90c06, com.vision.project.security.JwtAuthenticationTokenFilter@7c447c76, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@72715e61, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5611bba, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5a51336a, org.springframework.security.web.session.SessionManagementFilter@386e9fd8, org.springframework.security.web.access.ExceptionTranslationFilter@5403431a, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@58b8f9e3]
""2019-02-10 09:30:07 - Initializing ExecutorService 'taskScheduler'
""2019-02-10 09:30:07 - Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
""2019-02-10 09:30:07 - Tomcat started on port(s): 8080 (http) with context path ''
""2019-02-10 09:30:07 - Started ProjectApplication in 13.85 seconds (JVM running for 15.214)
""2019-02-10 09:31:09 - Initializing Spring DispatcherServlet 'dispatcherServlet'
""2019-02-10 09:31:09 - Initializing Servlet 'dispatcherServlet'
""2019-02-10 09:31:09 - Completed initialization in 16 ms
""2019-02-10 09:31:09 - Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
""2019-02-10 09:31:09 - Found thread-bound EntityManager [SessionImpl(1272634933<open>)] for JPA transaction
""2019-02-10 09:31:09 - Creating new transaction with name [com.vision.project.services.OrderServiceImpl.findAll]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.RuntimeException,-java.lang.Exception
""2019-02-10 09:31:09 - Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7234e97]
""2019-02-10 09:31:09 - Found thread-bound EntityManager [SessionImpl(1272634933<open>)] for JPA transaction
""2019-02-10 09:31:09 - Participating in existing transaction
""2019-02-10 09:31:09 - Found thread-bound EntityManager [SessionImpl(1272634933<open>)] for JPA transaction
""2019-02-10 09:31:09 - Participating in existing transaction
""2019-02-10 09:31:09 - Initiating transaction rollback
""2019-02-10 09:31:09 - Rolling back JPA transaction on EntityManager [SessionImpl(1272634933<open>)]
""2019-02-10 09:31:09 - Not closing pre-bound JPA EntityManager after transaction
""2019-02-10 09:31:09 - Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
""2019-02-10 09:31:09 - Closing JPA EntityManager

我为那些跳过更新的人回答我的问题。过了一段时间,我意识到:

    orderRepository.save(order1);
    orderRepository.save(order2);
    Order order = orderRepository.save(order3);
    order.setDishesReady = 5;
    orderRepository.delete(order3);
    if(order3.getDishesReady() == 5){
        throw new RuntimeException();
    }
只是对删除进行回滚,而不是对保存进行回滚。经过进一步研究,我发现我的表被设置为MyISAM,而不是InnoDB。 关于该主题的更多信息:

如果您需要数据库来实施外键约束,或者需要数据库来支持事务(即,两个或多个DML操作作为单个工作单元进行的更改,所有更改都已应用,或者所有更改都已还原),那么您可以选择InnoDB引擎,因为MyISAM引擎没有这些功能


让我们增加日志级别来跟踪,看看我们得到了什么。设置
org.springframework.transaction
包日志记录级别为
trace
debug
@dgregory,此时settin logging.level.org.springframework=跟踪缺少的某些bean,但“匹配”或“找到”其他bean。我尝试设置explicity logging.level.org.springframework.transaction=trace,所有关于事务Bean的信息都消失了,但类型为:Bean'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration'[org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$c2c8b097]不符合由所有BeanPostProcessor处理的条件(例如:不符合自动代理的条件)@dgregory I从日志中更新了一些问题:它正在启动事务roolback,然后它还说:不在事务之后关闭预先绑定的JPA EntityManager。而且它正在多次创建和关闭EntityManager。这正常吗?只需要在“回滚”中声明已检查的异常属性,默认情况下将回滚未选中的属性。我已经尝试了您的代码,效果很好。可能您的依赖项有问题。同意@heyza22,多次创建和关闭EntityManager看起来不正常。@JoseLuis使用gradle 4.4和java 1.8更新了我的依赖项问题
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-starter-security")
    testCompile('org.springframework.boot:spring-boot-starter-test')
    compile "org.springframework.boot:spring-boot-configuration-processor"
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.1.2.RELEASE'
    compile group: 'org.springframework', name: 'spring-jdbc', version: '5.0.8.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '1.2.5.RELEASE'
    compile group: 'org.springframework.security', name: 'spring-security-jwt', version: '1.0.2.RELEASE'

    compile group: 'org.hibernate', name: 'hibernate-core', version: '5.4.1.Final'
    compile group: 'org.hibernate', name: 'hibernate-gradle-plugin', version: '5.3.5.Final'

    compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.6.0'
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
    compile group: 'com.mchange', name: 'c3p0', version: '0.9.5.2'
    orderRepository.save(order1);
    orderRepository.save(order2);
    Order order = orderRepository.save(order3);
    order.setDishesReady = 5;
    orderRepository.delete(order3);
    if(order3.getDishesReady() == 5){
        throw new RuntimeException();
    }