Java Spring@Transaction rollbackfor和自定义存储库
我有一个事务没有回滚,我不明白为什么,我将它与自定义存储库一起使用,所以不确定这是否是问题所在,是否EntityManager正在不同的事务范围中运行 这是我的服务:Java Spring@Transaction rollbackfor和自定义存储库,java,spring,transactions,spring-data,Java,Spring,Transactions,Spring Data,我有一个事务没有回滚,我不明白为什么,我将它与自定义存储库一起使用,所以不确定这是否是问题所在,是否EntityManager正在不同的事务范围中运行 这是我的服务: @Service public class SchedulingProgramService { @Autowired SchedulingProgramRepository schedulingprogramRepository; @Transactional(rollbackFor = Excepti
@Service
public class SchedulingProgramService {
@Autowired
SchedulingProgramRepository schedulingprogramRepository;
@Transactional(rollbackFor = Exception.class)
public SchedulingProgram activateSchedulingProgram(String id) throws Exception {
SchedulingProgram schedulingprogram = schedulingprogramRepository.findOne(id);
if (schedulingprogram != null) {
schedulingprogramRepository.deactivateAllSchedulingPrograms();
if (true) //Just to test if rollback works
throw new Exception("");
schedulingprogram.accepted = true;
schedulingprogramRepository.save(schedulingprogram);
return schedulingprogram;
} else {
throw new NotFoundException();
}
}
}
我的自定义存储库界面:
public interface SchedulingProgramRepositoryCustom {
void deactivateAllSchedulingPrograms();
}
和执行:
public class SchedulingProgramRepositoryImpl implements SchedulingProgramRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void deactivateAllSchedulingPrograms()
{
Query query = entityManager.createQuery("update SchedulingProgram sp set accepted = :accepted WHERE accepted = :accepted2");
query.setParameter("accepted", false);
query.setParameter("accepted2", true);
query.executeUpdate();
}
}
最后是实际的存储库:
@Repository
@Transactional(readOnly = true)
public interface SchedulingProgramRepository extends PagingAndSortingRepository<SchedulingProgram, String>, SchedulingProgramRepositoryCustom {
@Modifying
@Transactional
void deactivateAllSchedulingPrograms();
}
@存储库
@事务(只读=真)
公共接口SchedulingProgramRepository扩展了分页和排序存储库,SchedulingProgramRepositoryCustom{
@修改
@交易的
无效停用所有检查程序();
}
我直接在服务中抛出一个异常只是为了测试,正如您所看到的,我已将rollbackor设置为Exception.class,因此我假设在deactivateAllSchedulingPrograms中所做的更改将回滚,但它们没有回滚。
自定义存储库中的EntityManager是否导致问题
我也不确定应该将哪些deactivateAllSchedulingPrograms方法注释为@Transactional,在SchedulingProgramRepository中注释该方法就足够了,还是还需要在SchedulingProgramRepositoryImpl中注释该方法?我两种方法都试过了,没有什么不同。事实上,我认为即使不注释它们,这也应该有效,因为我的服务方法是用@Transactional注释的,但我显然在这里做错了什么
更新
维哈尔,是的,我有:
<!-- Set session factory -->
<bean id="baseEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="baseDataSource" />
<property name="packagesToScan" value="myproject.model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">${base.db.dialect}</prop>
</props>
</property>
</bean>
<!-- Set transaction manager -->
<bean id="baseTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="baseEntityManagerFactory" />
</bean>
更新
${base.db.dialogue}
我错过什么了吗
problemMaker101,我知道我只能在服务中使用它们,但我认为在存储库中也使用它们是一个好策略。如果我不使用代理也访问这些方法呢?在两者上使用它们更安全,因为Spring文档也声明了这一点没有问题。我唯一的疑问是,我是否需要将@Transaction同时添加到SchedulingProgramRepository和SchedulingProgramRepositoryImpl中,或者只添加到其中一个中。从接口中删除@Transactional,并将服务impl类设为@Transactional(rollboor=“Throwable.class”) 在spring配置文件中,您是否定义了
transactionManager
bean?简单地将一个方法标记为transactional不起作用将\@transactional放在repository类中不是一个好的做法,也可以引用Spring文档中的一句话:“当使用代理时,您应该只将\@transactional注释应用于具有公共可见性的方法”。在服务类中设置\@Transactional就足够了。我试图回复您的评论,但似乎只能使用少量字符。所以你需要把它作为一个答案发布…@mfc:你可以通过“编辑”链接用更多信息修改你的问题。这次我是为你做的。