交易悄然回滚

问题描述 投票:0回答:1
@Modifying     
@Transactional
@Query("DELETE FROM BusinessTransaction bt WHERE bt.userId.id=:id")     
void deleteByUserId(Long id); 

对于此查询,我收到以下错误:

事务默默回滚,因为它已被标记为仅回滚

在此查询中,

userID
User
类的对象,与
BusinessTransaction
类连接并映射,因此在
where
条件下,我尝试从
userId.id
获取用户的ID,它应该与
相同:id
变量。

任何人都可以帮我解决这个错误吗?

java spring-boot jpql
1个回答
0
投票

您的代码看起来正确。问题应该出在使用的地方。

如果您在另一个事务方法中抑制 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
    }
}

有几种可能的解决方案:

  1. 将事务传播更改为 NESTED(但并非所有数据库都实现嵌套事务):
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);
}
  1. 尝试使用Propagation.REQUIRES_NEW。在这种情况下将创建新的独立事务。检查这是否适合您。 Spring事务中requires_new和嵌套传播的区别

  2. 回顾处理事务的逻辑。例如,您可以将操作拆分为多个操作并实现有限状态机。 https://felixge.de/2017/07/27/implementing-state-machines-in-postgresql/

© www.soinside.com 2019 - 2024. All rights reserved.