本文講解 Spring Boot 如何使用宣告式事務管理。
部落格地址:blog.720ui.com/
宣告式事務
Spring 支援宣告式事務,使用 @Transactional 註解在方法上表明這個方法需要事務支援。此時,Spring 攔截器會在這個方法呼叫時,開啟一個新的事務,當方法執行結束且無異常的情況下,提交這個事務。
Spring 提供一個 @EnableTransactionManagement 註解在配置類上來開啟宣告式事務的支援。使用了 @EnableTransactionManagement 後,Spring 會自動掃描註解 @Transactional 的方法和類。
Spring Boot預設整合事務
Spring Boot 預設整合事務,所以無須手動開啟使用 @EnableTransactionManagement 註解,就可以用 @Transactional註解進行事務管理。我們如果使用到 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa,Spring Boot 會自動預設分別注入 DataSourceTransactionManager 或 JpaTransactionManager。
實戰演練
我們在前文「Spring Boot 揭祕與實戰(二) 資料儲存篇 - MySQL」的案例上,進行實戰演練。
實體物件
我們先建立一個實體物件。為了便於測試,我們對外提供一個構造方法。
public class Author {
private Long id;
private String realName;
private String nickName;
public Author() {}
public Author(String realName, String nickName) {
this.realName = realName;
this.nickName = nickName;
}
// SET和GET方法
}複製程式碼
DAO 相關
這裡,為了測試事務,我們只提供一個方法新增方法。
@Repository("transactional.authorDao")
public class AuthorDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public int add(Author author) {
return jdbcTemplate.update("insert into t_author(real_name, nick_name) values(?, ?)",
author.getRealName(), author.getNickName());
}
}複製程式碼
Service 相關
我們提供三個方法。通過定義 Author 的 realName 欄位長度必須小於等於 5,如果欄位長度超過規定長度就會觸發引數異常。
值得注意的是,noRollbackFor 修飾表明不做事務回滾,rollbackFor 修飾的表明需要事務回滾。
@Service("transactional.authorService")
public class AuthorService {
@Autowired
private AuthorDao authorDao;
public int add1(Author author) {
int n = this.authorDao.add(author);
if(author.getRealName().length() > 5){
throw new IllegalArgumentException("author real name is too long.");
}
return n;
}
@Transactional(noRollbackFor={IllegalArgumentException.class})
public int add2(Author author) {
int n = this.authorDao.add(author);
if(author.getRealName().length() > 5){
throw new IllegalArgumentException("author real name is too long.");
}
return n;
}
@Transactional(rollbackFor={IllegalArgumentException.class})
public int add3(Author author) {
int n = this.authorDao.add(author);
if(author.getRealName().length() > 5){
throw new IllegalArgumentException("author real name is too long.");
}
return n;
}
}複製程式碼
測試,測試
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(WebMain.class)
public class TransactionalTest {
@Autowired
protected AuthorService authorService;
//@Test
public void add1() throws Exception {
authorService.add1(new Author("樑桂釗", "樑桂釗"));
authorService.add1(new Author("LiangGzone", "LiangGzone"));
}
//@Test
public void add2() throws Exception {
authorService.add2(new Author("樑桂釗", "樑桂釗"));
authorService.add2(new Author("LiangGzone", "LiangGzone"));
}
@Test
public void add3() throws Exception {
authorService.add3(new Author("樑桂釗", "樑桂釗"));
authorService.add3(new Author("LiangGzone", "LiangGzone"));
}
}複製程式碼
我們分別對上面的三個方法進行測試,只有最後一個方法進行了事務回滾。
原始碼
相關示例完整程式碼: springboot-action
(完)
更多精彩文章,盡在「服務端思維」微信公眾號!