我有一個方法被定義爲@transactional。事實上,我有一個方法調用一個方法,所有三個都是@transactional。事務邏輯運行良好,直到我抽出幾個方法進入抽象類來重用某些代碼,這似乎破壞了我的邏輯。交易方法拋出「沒有事務性的entityManager可用」
的交易方法是從一個抽象類,這裏是有關部分的部分片段(我有手工重寫這個所以請原諒我的拼寫錯誤):
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延伸上述抽象類,並使用相同的方法保存不加改變地addPermissions是調用保存在每個權限的for循環。
entityTypeService有效,但permissionService失敗。如果我在執行em.isTransactionalEntity時調用權限服務,它將返回false。
所有@transactional註解都使用spring註釋,而不是javax。
實際上,好像少數權限會保存,其他人不會,幾乎就像它是非確定性的,但這可能很簡單,因爲修改了一些數據庫文件,這些文件有一些已經設置的值因此不需要第一次運行某些邏輯。
我已經做了相當多的磕磕絆絆,但我沒有接近確定什麼會導致我的交易結束。我曾想過可能是@persistenceContext,因爲JPARepos通過一種不同的方法獲得他們的entityManager,然後使用@persistenceContext自動裝載,但是如果那樣的話一切都會失敗?
任何幫助將不勝感激,我非常難倒在這個原因。