Apache Ignite SpringTransactionManager не выполняет откат транзакции.
зажигать 2.7.5, пружинный башмак 2.1.6
Организация:
@Data
@AllArgsConstructor
public class CacheEntity {
@QuerySqlField
private String uuid;
}
Repository:
@RepositoryConfig(cacheName = CACHE_NAME)
public interface TestRepository extends IgniteRepository<CacheEntity, Long> {
}
Тест
@ActiveProfiles(profiles = {"junit"})
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = IgniteRepositoryTransactionTest.Config.class)
public class IgniteRepositoryTransactionTest {
public static final String CACHE_NAME = "testCache";
@Autowired
private Ignite ignite;
@Autowired
private SpringTransactionManager ignitePessimisticTransactionManager;
@Autowired
private TestRepository repository;
@Test
public void txTest() {
ignite.cache(CACHE_NAME).clear();
try {
final TransactionTemplate txTemplate = new TransactionTemplate(ignitePessimisticTransactionManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute((TransactionCallback<Void>) status -> {
// ignite.cache(CACHE_NAME).put(1L, new CacheEntity(UUID.randomUUID().toString()));
repository.save(1L, new CacheEntity(UUID.randomUUID().toString()));
throw new RuntimeException("exception during transaction");
});
} catch (RuntimeException ignored) {
}
assertFalse("not saved", repository.findById(1L).isPresent());
// assertNull("not saved", ignite.cache(CACHE_NAME).get(1L));
}
@TestConfiguration
@EnableIgniteRepositories(basePackageClasses = {TestRepository.class})
@EnableTransactionManagement
public static class Config {
@Bean
public IgniteConfiguration igniteConfiguration() {
IgniteConfiguration icfg = new IgniteConfiguration();
icfg.setClientMode(false);
icfg.setIgniteInstanceName(CACHE_NAME + "-instance");
icfg.setPeerClassLoadingEnabled(true);
CacheConfiguration<Long, CacheEntity> ccf = new CacheConfiguration<>(CACHE_NAME);
ccf.setIndexedTypes(Long.class, CacheEntity.class);
icfg.setCacheConfiguration(ccf);
return icfg;
}
@Bean
public Ignite igniteInstance() {
return Ignition.start(igniteConfiguration());
}
@Bean
public SpringTransactionManager ignitePessimisticTransactionManager() {
final SpringTransactionManager transactionManager = new SpringTransactionManager();
transactionManager.setIgniteInstanceName(igniteInstance().name());
transactionManager.setTransactionConcurrency(TransactionConcurrency.PESSIMISTIC);
transactionManager.setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
return transactionManager;
}
}
}
Я вижу, что логика отката активируется, и никаких исключений нет. Но, наконец, сущность сохраняется во время сбойной операции сохранения.
То же самое с использованием экземпляра ignite вместо хранилища.
23: 54: 15.049 [main] DEBUG org.apache.ignite.transactions.spring.SpringTransactionManager - создание новой транзакции с именем [null]: PROPAGATION_REQUIRED, ISOLATION_DEFAULT
23: 54: 15.119 [main] DEBUG org.springframework.transaction.support.TransactionTemplate - инициирование отката транзакции при исключении приложения
UPDATE :
Спасибо alamar комментарий. Режим транзакционного кэша по умолчанию отключен:
ccf.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);