I have a service that tries to persist two entites. My expectation is that if one entity is failed to persist, other one should be rolled back and not persisted. But one is persisted while another one is not. Here is my service class
@Service
@Transactional(value = "db1TransactionManager")
public class ServiceImpl {
@Override
@Transactional
public void insertOrUpdate(Entity1 entity1, Entity2 entity2) {
db1Repository.insert(entity1, Entity1.class);
db1Repository.insert(entity1, Entity2.class);
}
}
And here is my repositroy class
@Transactional(value = "db1TransactionManager")
@Repository(value = "db1Repository")
public class Db1RepositoryImpl {
@PersistenceContext(unitName = "db1")
private EntityManager em;
@Override
public <T> void insert(T entity, Class<T> tClass) {
em.persist(entity);
// em.flush();
}
}
I am intentionally setting entity2 as null to check if rollback works, but entity1 is still persisted. How do i make this transaction atomic?
CodePudding user response:
According to the spring transaction propagation mechanism
The default is PROPAGATION_REQUIRED
We either succeed together or we fail together
So far you appear more like PROPAGATION_NESTED
In other words, the two inserts are not in the same transaction
CodePudding user response:
I am not sure exactly why is this happening but finally solved the problem by removing @Transactional(value = "db1TransactionManager")
from repository and placing it on top of the method. Also removed it from class level of service.
Still looking for a proper explanation.
So here is how it looks now
@Service
public class ServiceImpl {
@Override
@Transactional(value = "db1TransactionManager")
public void insertOrUpdate(Entity1 entity1, Entity2 entity2) {
db1Repository.insert(entity1, Entity1.class);
db1Repository.insert(entity1, Entity2.class);
}
}
and
@Repository(value = "db1Repository")
public class Db1RepositoryImpl {
@PersistenceContext(unitName = "db1")
private EntityManager em;
@Override
public <T> void insert(T entity, Class<T> tClass) {
em.persist(entity);
// em.flush();
}
}