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