【发布时间】:2015-09-15 13:44:53
【问题描述】:
我有一个定义为@transactional 的方法。实际上我有一个方法调用一个方法调用一个方法,这三个都是@transactional。事务逻辑运行良好,直到我将一些方法提取到抽象类中以进行代码重用,这似乎以某种方式破坏了我的逻辑。
事务方法来自一个抽象类,这里是相关部分的部分sn-p(我必须手动重写,所以请原谅我的错别字):
public abstract class ReadWriteService<ReadEntityTempalte extends IEntity, WriteEntityTemplate extends IEntity>
//extends jpaRepository, created using @enableJpaRepositories
private searchRepository<WriteEntityTemplate, String> writeRepository;
@PersistenceContext
private EntityManager em;
@transactional
public ReadEntityTemplate save(final WriteEntityTemplate entity){
if(entity == null) return null;
WriteEntityTemplate returnValue = writeRepository_.save(entity);
postSave(returnValue); //checks our security logic
flush();
ReadEntityTemplate returnEntity = find(returnValue.getId());
//required to detect changes made to the view by our save
em.refresh(returnEntity);
}
之所以这样写,是因为我们使用的是视图,因此可以在 find() 中将返回值修改为视图。此逻辑在过去有效,并且仍然适用于许多调用。
失败的方法是:
@Override
@transational
public void configure(EntityFileConfig config) throws ClassNotFoundException{
//load config from file
for(EntityConfig entityConfig: entityConfigs){
EntityType entityType=EntityTypeService_.find(entityConfig.getKey());
if(entityType==null){
entityType = EntityType.createByRequiredFields(entityConfig.getKey());
}
//update entityType to reflect config file.
entityType = entityTypeService_.save(entityType);
for(String permissionName: entityConfig.getPermissions()){
if(!entityTypeService_.hasPermission(entityType, permissionName)){
Permission permission = permissionSetup.getPermission(permissionName);
if(permission!=null)
//fails on below lines
permissionService._.addPermission(entityType, permission);
}
}
}
}
entityTypeService 和permissionService 都扩展了上述抽象类并使用相同的save 方法而不做任何改动,addPermissions 是一个forloop,在每个权限上调用save。
entityTypeService 工作,但是 permissionService 失败。当我执行 em.isTransactionalEntity 调用权限服务时,它返回 false。
所有@transactional注解都使用spring注解,而不是javax注解。
实际上,似乎有一些权限会保存而其他权限不会保存,几乎就好像它是不确定的,但这可能很简单,因为修改了已经设置了一些值的数据库文件,并且因此不需要在第一次运行某些逻辑。
我已经做了很多绊脚石,但还没有确定什么会导致我的交易结束。我原以为可能是 @persistenceContext,因为 JPARepos 通过不同的方法获取他们的 entityManager,然后使用 @persistenceContext 进行自动装配,但如果是这样的话,一切都会失败吗?
任何帮助将不胜感激,我对这个原因感到很困惑。
【问题讨论】:
标签: java spring transactions