Spring事務回滾的兩種方法
theme: Chinese-red
持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第30天,點選檢視活動詳情
當然,Spring事務回滾的前提是你當前使用的資料庫必須支援事務,比如MySQL的Innodb是支援的,但Mysaim則是不支援事務的。
方法一
-
使用
@Transaction
來配置自動回滾,可以配置在類上,也可以配置在方法上(作用域不同),但對final或private修飾的方法無效,且該類必須是受spring所管控的,也就是被已經被注入的類,而不是new出來的類。- 若配置在方法上,則該方法被加上了事務
- 若配置在類上,則等於給該類的所有方法都加上了該註解。此時如果在該類下的某個方法也加了
@Transaction
,則該方法使用自己的配置,其他方法使用類上的配置。
java
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Override
public void save(User user) {
//some code
//db operation
}
}
-
若被配置的方法或類丟擲了異常,則事務會被自動回滾,除非你在該方法中手動捕獲了異常,且沒有丟擲新的異常。
可以使用
@Transactional(rollbackFor = Exception.class)
來設定針對特定的異常進行事務回滾,如果不設定則預設會回滾 RuntimeException and Error (參考自原始碼內文件)。```java @Service @Transactional(rollbackFor = Exception.class) public class UserServiceImpl implements UserService { @Resource private UserMapper userMapper;
@Override public void save(User user) { userMapper.insert(user); throw new RuntimeException(); // 丟擲異常,事務回滾,上面的insert插入失敗。 }
} ```
方法二
通過注入 DataSourceTransactionManager
來手動開啟事務,手動回滾事務,用於丟擲異常被catch後,進行手動回滾,可控程度更高,可以更靈活的使用。
- 先注入
DataSourceTransactionManager
事務管理物件 - new 一個
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
物件 - 使用
TransactionStatus status = transactionManager.getTransaction(def);
來開啟一個事務, - 使用
transactionManager.rollback(status);
來回滾這個事務 - 使用
transactionManager.commit(status);
來提交這個事務
```java @Service public class UserServiceImpl implements UserService { @Autowired private DataSourceTransactionManager transactionManager;
@Override @Transactional public void save(User user) { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can only be done programmatically def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
//db operation
} catch (Exception ex) {
transactionManager.rollback(status);
throw ex;
}
} } // 此程式碼案例來自Alibaba Coding Guidelines ```