springboot jta事务回滚不起作用 [英] springboot jta transaction rollback is not working

查看:863
本文介绍了springboot jta事务回滚不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用JTA(使用atomikos)配置在整个数据库中执行事务.

I want to perform transaction across database using JTA (using atomikos) configuration.

我有以下代码,希望在一次交易中执行.但是,当我运行该应用程序时,它会保存entityObject1并更新eventObject2,并且在运行l.intValue()语句时引发异常时不会回滚.下面是我用于JTA配置的所有代码.

I have below code which I wanted to perform in one transaction. However when I run the application, it saves entityObject1 and update eventObject2 and doesnt rollback when an exception is thrown when i run l.intValue() statement. below is all code that I am using with configuration for JTA.

我想念什么吗?谁能帮忙.

Am i missing anything? Could anyone please help.

public void testJTATRansaction() {
    service1.saveEvent1(eventObject1);
    service2.updateEvent2(eventObject2);
}           

service1中的saveEvent1方法:

saveEvent1 method in service1:

@Transactional(propagation=Propagation.REQUIRED, rollbackFor = Exception.class)
public int saveEvent1(Object eventObject1) {
    return repository1.save(eventObject1);
}

service2中的updateEvent2方法:

updateEvent2 method in service2:

@Transactional(propagation=Propagation.REQUIRED, rollbackFor = Exception.class)
public int updateEvent2(Object eventObject2) {
    int i = l.intValue();   //l is null object, to throw error
    return repository2.updateEvent2(eventObject2);
}

我正在使用来自repository1的默认保存方法(JPARepository保存方法).

I am using default save method from repository1 (JPARepository save method).

repository2类中的updateEvent2方法:

updateEvent2 method in repository2 class:

@Modifying
@Transactional(propagation=Propagation.REQUIRED, rollbackFor = Exception.class)
@Query(UPDATE_EVENTS)
public int updateEvent2(
          @Param(value = "eventObject2") Object eventObject2);

我正在使用Spring Boot应用程序类来初始化我的应用程序:

I am using spring boot application class to initialise my application:

@SpringBootApplication
@ComponentScan("com.cbc.event")
@EnableTransactionManagement
public class RatingDaemonApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(RatingDaemonApplication.class);
    }
}

我具有以下JTA配置:

I have below JTA configuration:

@Configuration
@ComponentScan
@EnableTransactionManagement
public class JTATransactionConfig {

@Bean
public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    hibernateJpaVendorAdapter.setShowSql(true);
    hibernateJpaVendorAdapter.setGenerateDdl(true);
    hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
    return hibernateJpaVendorAdapter;
}

@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
    UserTransactionImp userTransactionImp = new UserTransactionImp();
    userTransactionImp.setTransactionTimeout(10000);
    return userTransactionImp;
}

@Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
public TransactionManager atomikosTransactionManager() throws Throwable {
    UserTransactionManager userTransactionManager = new UserTransactionManager();
    userTransactionManager.setForceShutdown(false);

    AtomikosJtaPlatform.transactionManager = userTransactionManager;

    return userTransactionManager;
}

@Bean(name = "transactionManager")
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
public PlatformTransactionManager transactionManager() throws Throwable {
    UserTransaction userTransaction = userTransaction();

    AtomikosJtaPlatform.transaction = userTransaction;

    TransactionManager atomikosTransactionManager = atomikosTransactionManager();
    return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
}

}

,数据源配置为:

@Configuration
@DependsOn("transactionManager")
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(basePackages = {"com.cbc.repository"}, 
    transactionManagerRef="transactionManager", entityManagerFactoryRef = "entityMF")
public class dataSourceConfiguration {

    @Autowired
    Environment env;

    @Autowired
    JpaVendorAdapter jpaVendorAdapter;

    public DataSource eventsDS() {

        AtomikosDataSourceBean xaDS = new AtomikosDataSourceBean();
        xaDS.setXaDataSourceClassName(env.getProperty(DRIVER_CLASS_NAME));
        xaDS.setXaDataSource(getMysqlXADataSource());       
        xaDS.setUniqueResourceName("DS");
        xaDS.setMaxPoolSize(3);
        return xaDS;
    }

    private MysqlXADataSource getMysqlXADataSource() {
        MysqlXADataSource ds = new MysqlXADataSource();
        ds.setPinGlobalTxToPhysicalConnection(true);
        ds.setURL(env.getProperty(URL));
        ds.setUser(env.getProperty(USER));
        ds.setPassword(env.getProperty(PASSWORD));
        return ds;
    }

    @Bean(name="entityMF")
    public LocalContainerEntityManagerFactoryBean importedEventsEntityMF() {
        Map<String, Object> properties = new HashMap<>();
        properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
        properties.put("javax.persistence.transactionType", "JTA");

        LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
        entityManager.setJtaDataSource(eventsDS());
        entityManager.setJpaVendorAdapter(jpaVendorAdapter);
        entityManager.setPackagesToScan("com.cbc.events");
        entityManager.setPersistenceUnitName("persistenceUnit");
        entityManager.setJpaPropertyMap(properties);
        return entityManager;
    }
}

我在AtomikosJtaPlatform类之下

I have below AtomikosJtaPlatform class

public class AtomikosJtaPlatform extends AbstractJtaPlatform {

    private static final long serialVersionUID = 1L;

    static TransactionManager transactionManager;
    static UserTransaction transaction;

    @Override
    protected TransactionManager locateTransactionManager() {
        return transactionManager;
    }

    @Override
    protected UserTransaction locateUserTransaction() {
        return transaction;
    }
}

推荐答案

仅当您使用JNDI时,JTA事务管理器才能工作. JTA tx管理器仅在数据源bean在Java/Web容器中而不在应用程序中时,才侦听数据源并进行事务处理.容器.

JTA transaction manager will only work if you use JNDI. JTA tx manager listens to Datasource and bring under a transaction only if the datasource bean is in Java/Web container and not in app. container.

您需要使用JNDI来使JTA工作或开始使用JPA事务管理器. JTA事务管理器主要用于分布式事务中,并且容易发生事务回滚失败.

Either you need to use JNDI for JTA to work or start using JPA transaction manager. JTA transaction manager is mainly used in Distributed Transaction and is prone to transaction rollback failures.

这篇关于springboot jta事务回滚不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆