Возможно ли транзакционное расширение на другие операции больше, чем на db в Spring? - PullRequest
2 голосов
/ 24 марта 2020

Объясняю контекст:

Я реализовал экспорт и импорт записей из двух разных баз данных, другими словами, refre sh из семи таблиц. Я использовал JdbcCursorItemReader для выполнения запросов на отдельные фрагменты, потому что для каждой таблицы существует более 600000 записей, и сохранял каждый фрагмент с помощью пакетной вставки jdb c в другой БД. Идея претворена в жизнь:

ЗАМЕЧАНИЕ по требованию : все таблицы должны обновляться в уникальной транзакции, если только откат какой-либо таблицы не может выполнить откат

У меня есть создал уникальный метод, который очищает, экспортирует / импортирует в чанк для каждой таблицы в уникальной транзакции.

Класс с аннотацией

@Transactional

Мне нужно сделать те же логи c, в в то же время очистить и заполнить кэш, реализованный с помощью ConcurrentHashMap

В двух словах:

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 

Вопрос:

Может ли аннотация транзакции применить logi c коммит или откат также ConcurrentHashMap?

Спасибо

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Я сделал простой тест, чтобы понять, работает ли реализация нормально. Без аннотации @Transactional он работает в следующей конфигурации:

импортированные зависимости:

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'

Класс конфигурации:

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;
    }

}

Тестовый класс

@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();
    }

}

Кэш работает, но я бы хотел @Transactional реализацию аннотации для метода, так как я уже создал два компонента Transactional bean для двух разных баз данных.

Знаете ли вы, где я могу найти пример реализации ?

2 голосов
/ 24 марта 2020

EHCache 2.4+ работает с аннотацией Spring * @Transactional.

...