@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;
}