问题
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