我有一个定义为@transactional的方法。实际上我有一个方法调用一个调用方法的方法,所有三个都是@transactional。事务逻辑工作正常,直到我将一些方法拉出到一个抽象类中以进行一些代码重用,这似乎已经破坏了我的逻辑。
事务方法来自一个抽象类,这里是相关部分的部分片段(我必须手工重写这个,所以请原谅我的错别字):
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自动装配,但如果是这样的话,一切都会失败?
任何帮助都会受到赞赏,我对这个原因感到非常难过。
答案 0 :(得分:0)
假设您在@EnableTransactionManagement
课程上启用了@Configuration
。
由于您未在@Transaction
上设置任何传播,因此默认值为Required
。这意味着所有方法都必须是交易的一部分。由于您的一个抽象方法不属于@Transactional
因此错误。
For more information on Spring Transactions
注意:从上面链接拍摄的图像。