@Modifying
@Transactional
@Query("DELETE FROM BusinessTransaction bt WHERE bt.userId.id=:id")
void deleteByUserId(Long id);
对于此查询,我收到以下错误:
事务默默回滚,因为它已被标记为仅回滚
在此查询中,
userID
是User
类的对象,与BusinessTransaction
类连接并映射,因此在where
条件下,我尝试从userId.id
获取用户的ID,它应该与相同:id
变量。
任何人都可以帮我解决这个错误吗?
您的代码看起来正确。问题应该出在使用的地方。
如果您在另一个事务方法中抑制 SQL 查询错误,则可能会出现此错误。看这个小例子。
public interface ArticleRepository extends JpaRepository<Article, Long> {
@Transactional
@Modifying
@Query("update Article set title = :title where id = :id")
void updateTitle(Long id, String newTitle);
}
public class DummyService {
@Transactional
public static void throwRollbackError(Long articleIdForUpdating, String articleNewTitle, Long articleIdForDeleting) {
try {
// for example transactional method "updateName" throws an exception
// because of title unique constraint failed error
articleRepo.updateTitle(articleIdForUpdating, articleNewTitle);
// use flush here to execute the update SQL query and throw the exception
articleRepo.flush();
} catch (DataIntegrityViolationException e) {
// the transaction marked as rollback-only now
e.printStackTrace();
}
// the delete query can't be executed now because of rollback-only transaction
articleRepo.deleteById(articleIdForDeleting);
// implicit call of flush() will try to execute the delete SQL query
// and throws the UnexpectedRollbackException
}
}
有几种可能的解决方案:
public interface ArticleRepository extends JpaRepository<Article, Long> {
@Transactional(propagation = Propagation.NESTED) // <-- if nested transaction rollbacked then outer one doesn't
@Modifying
@Query("update Article set title = :title where id = :id")
void updateTitle(Long id, String newTitle);
}
尝试使用Propagation.REQUIRES_NEW。在这种情况下将创建新的独立事务。检查这是否适合您。 Spring事务中requires_new和嵌套传播的区别
回顾处理事务的逻辑。例如,您可以将操作拆分为多个操作并实现有限状态机。 https://felixge.de/2017/07/27/implementing-state-machines-in-postgresql/