springboot Transaction事務的手動版(程式設計式事務)和自動版(宣告式事務)
阿新 • • 發佈:2021-02-04
技術標籤:springbooot 系列mysqljava事務併發springboot
1.spring管理的 自動 @Transaction() 宣告式事務
@Transaction(rollback=Exception.class)
public synchronized void test(){
// 查詢訂單數量
queryProductCount();
// 判斷訂單是否>0
if(){
throw Exception();
}
// 更新庫存
update();
// 插入一條訂單資料
insert();
}
CountDownLatch countDownLatch = new CountDownLatch(1);
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(()->{
try {
countDownLatch.await();
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
countDownLatch.countDown();
2. 手動事務 (程式設計式事務)
應用場景:當存在併發時,事務還未提交,synchronized方法已經執行完畢。如以上方法執行了五次,訂單被扣減了兩次。原因是註解事務是利用切面方式,當synchronized方法執行完,事務其實還沒提交。
解決方案:
1.手動提交事務,將事務置於synchronized修飾的方法內。
2.使用程式碼塊手動提交事務。
3.使用(Lock)ReentranLock。
方式一:
// 事務管理器
@Autowired
PlatformTransactionManager platformTransaction;
// 事務定義 :事務的一些基礎資訊,如超時時間、隔離級別、傳播屬性等
@Autowired
TransactionDefinition transactionDefinition;
public synchronized void test(){
// 事務的一些狀態資訊,如是否一個新的事務、是否已被標記為回滾
TransactionStatus transactionStatus = PlatformTransactionManager.getTransaction(transactionDefinition);
// 查詢訂單數量
queryProductCount();
// 判斷訂單是否>0
if(){
platformTransactionManager.rollback(transactionStatus);
throw Exception();
}
// 更新庫存
update();
// 插入一條訂單資料
insert();
platformTransactionManager.commit(transactionStatus);
}
方式二:
@Autowired
private TransactionTemplate transactionTemplate;
public synchronized void test(){
// 事務的一些狀態資訊,如是否一個新的事務、是否已被標記為回滾
/* 如果你的方法需要返回值請使用這個類
* new TransactionCallback<Object>()
*
* 如果你的方法不需要返回值那麼使用