@Transactional 错误使用的几种场景


@RestController
public class AController {

    @Autowired
    AService aService;

    // 回滚
    @GetMapping("direct")
    public void direct() {
        aService.testTransactional();
    }

    // 不回滚
    @GetMapping("indirect")
    public void indirect() {
        aService.testTransactionalIndirect();
    }

    // 不回滚
    @GetMapping("nonPublic")
    public void nonPublic() {
        aService.testTransactionalNonPublic();
    }

    // 不回滚
    @GetMapping("catchException")
    public void catchException() {
        aService.testTransactionalCatchException();
    }

    // 不回滚
    @GetMapping("sqlException")
    public void sqlException() throws SQLException {
        aService.testTransactionalSQLException();
    }

    // 回滚
    @GetMapping("sqlExceptionWithRollbackfor")
    public void sqlExceptionWithRollbackfor() throws SQLException {
        aService.testTransactionalSQLExceptionWithRollbackfor();
    }
}

 

@Service
public class AService {

    @Autowired
    TestTableDAO testTableDAO;

    // 回滚
    @Transactional
    public void testTransactional() {
        ATestTable er = new ATestTable();
        er.setSummary("test");
        testTableDAO.save(er);

        throw new RuntimeException("exception");
    }

    // 不回滚: 类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰
    public void testTransactionalIndirect() {
        testTransactional();
    }

    // 不回滚: @Transaction注解只对方法名为pubic的才生效
    @Transactional
    void testTransactionalNonPublic() {
        ATestTable er = new ATestTable();
        er.setSummary("test");
        testTableDAO.save(er);

        throw new RuntimeException("exception");
    }

    // 不回滚
    @Transactional
    public void testTransactionalCatchException() {
        ATestTable er = new ATestTable();
        er.setSummary("test");
        testTableDAO.save(er);

        try {
            throw new RuntimeException("exception");
        } catch (Exception e) {
            System.out.println("catch");
        }
    }

    // 不回滚: @Transactional默认情况下只回滚RuntimeException和Error
    @Transactional
    public void testTransactionalSQLException() throws SQLException {
        ATestTable er = new ATestTable();
        er.setSummary("test");
        testTableDAO.save(er);

        throw new SQLException("exception");
    }

    // 回滚: 指定在 SQLException 异常发生时回滚
    @Transactional(rollbackFor = {
            SQLException.class
    })
    public void testTransactionalSQLExceptionWithRollbackfor() throws SQLException {
        ATestTable er = new ATestTable();
        er.setSummary("test");
        testTableDAO.save(er);

        throw new SQLException("exception");
    }
}

 

@Repository
public interface TestTableDAO
        extends JpaRepository<ATestTable, Integer>, JpaSpecificationExecutor<ATestTable> {

}

 

@Entity
@Data
@Table(name = "test")
public class ATestTable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;

    @Column(name = "summary", length = 512)
    String summary;
}

 

 

 

发布了208 篇原创文章 · 获赞 32 · 访问量 20万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章