Is Transactional possible extend to other operations more than to db in Spring?

烂漫一生 提交于 2021-01-27 18:29:20

问题


I explain the context:

I implemented the export and import records from two differents Data base in other words a refresh of seven tables. I used JdbcCursorItemReader to perform the select chunked queries because there are over 600000 records for each table and save every chunk with jdbc batch insert on the other DB. The implented idea has been the followed:

REMARK on requirement: All tables must be refreshed in unique transaction, if only a chunk of any table fails rollback

I have created a unique method that purge, export/import to chunk for each table in a unique transaction.

Class with annotation

@Transactional

I need to do the same logic, at the same time, to purge and to populate a cache implemeted with ConcurrentHashMap

In a nutshell:

1) OPEN transaction
   1.1) purge table
   1.2) purge cache
   1.3) read data chunk from DataBase Oracle (1000 records at a time)
   1.4) insert data chunk on DataBase Postgresql (1000 records at a time)
   1.5) put data chunk in cache (ConcurrentHashMap 1000 records at a time)
2) if there aren't exceptions COMMIT all, otherwise ROLLBACK all for DB but also for
   ConcurrentHashMap 
3) CLOSE transaction 

The question is:

Is Transaction annotation able to apply the logic commit or rollback also ConcurrentHashMap ?

Thanks


回答1:


EHCache 2.4+ works with Spring's @Transactional annotation.




回答2:


I did a simple test to understand if the implementation works fine. Without @Transactional annotation it works in the followed configuration:

dependencies imported:

implementation group: 'org.ehcache', name: 'ehcache', version: '3.0.0'
// https://mvnrepository.com/artifact/org.codehaus.btm/btm
testImplementation group: 'org.codehaus.btm', name: 'btm', version: '2.1.4'

Configuration class:

import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.transactions.xa.configuration.XAStoreConfiguration;
import org.ehcache.transactions.xa.txmgr.btm.BitronixTransactionManagerLookup;
import org.ehcache.transactions.xa.txmgr.provider.LookupTransactionManagerProviderConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import bitronix.tm.BitronixTransactionManager;
import bitronix.tm.TransactionManagerServices;


@Configuration
public class CacheConfig {


    @Bean(value = "bitronixTransactionManager")
    public BitronixTransactionManager bitronixTransactionManager() {
        BitronixTransactionManager transactionManager =  TransactionManagerServices.getTransactionManager();

        return transactionManager;
    }


    @Bean(value = "cacheSreManager")
    public CacheManager buildCacheManager() {

        BitronixTransactionManager transactionManager = TransactionManagerServices.getTransactionManager();
        CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .using(new LookupTransactionManagerProviderConfiguration(BitronixTransactionManagerLookup.class)) 
                .withCache("xaCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, 
                                                                    ResourcePoolsBuilder.heap(10)) 
                    .add(new XAStoreConfiguration("xaCache")) 
                    .build()
                )
                .build(true);
        return cacheManager;
    }

}

Test class

@Service("sreEvolutionService")
public class SreEvolutionServiceImpl implements SreEvolutionService {

    @Autowired
    @Qualifier("sreDao")
    private SreDao sreDao;

    @Autowired
    @Qualifier("cacheSreManager")
    private CacheManager cacheManager;

    @Autowired
    @Qualifier("bitronixTransactionManager")
    private BitronixTransactionManager btx;


    @Override
    public void testTxCache() throws Exception {
        Cache<String, String> xaCache  = cacheManager.getCache("xaCache", String.class, String.class);
        try {
            addCache();

            System.out.println(xaCache.get("test2"));
        } catch (Exception e) {
            e.printStackTrace();
            xaCache.get("test2");
        }


    }   

    public void addCache() throws Exception{

        btx.begin();
        Cache<String, String> xaCache  = cacheManager.getCache("xaCache", String.class, String.class);
        xaCache.put("test2", "test2");
        if (1==1) {
            btx.rollback();
            throw new Exception("error test for cache tx");

        }

        btx.commit();
    }

}

The cache works but I'd like @Transactional annotation implementation on the method, advancing that I have already instantiated two Transactional beans for two DataBase different.

Do you know where can I find the implementation example ?



来源:https://stackoverflow.com/questions/60833562/is-transactional-possible-extend-to-other-operations-more-than-to-db-in-spring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!