Springboot在有鎖的情況下正確使用事務的實現代碼
1. 概述
老話說的好:想要賺錢,就去看看有錢人有什么需求,因為有錢人錢多,所以賺的多。
言歸正傳,在Java項目的研發(fā)中,“鎖”這個詞并不陌生,最經典的使用場景是商品的超賣問題。
很多Java小白,通常會認為,給代碼加上一把“鎖”,就能解決多扣庫存問題,卻忽略了數據庫事務的問題,今天我們就來做一個實驗,分析一下商品超賣問題。
2. 場景介紹
有一款商品,庫存只剩1件。
購買商品時,做三個動作,一是檢查庫存,二是扣庫存,三是生成訂單,三個動作在一個事務中執(zhí)行。
模擬并發(fā)場景,使用10個線程同時執(zhí)行用戶購買商品的操作。
3. 代碼實現
3.1 不加鎖的代碼實現
@Transactional(rollbackFor = Exception.class)
public void buy() {
// 查看是商品否有庫存
Integer count = getProductCount();
if(count <= 0) {
throw new RuntimeException("庫存為 0");
}
// 減庫存
productRepository.reductCount();
// 生成訂單
createOrder();
}
首先我們正常編寫業(yè)務邏輯,用 @Transactional 注解控制事務。
經并發(fā)實驗,產生了超賣的現象。
3.2 加鎖的代碼實現
@Transactional(rollbackFor = Exception.class)
public synchronized void buy() {
// 查看是商品否有庫存
Integer count = getProductCount();
if(count <= 0) {
throw new RuntimeException("庫存為 0");
}
// 減庫存
productRepository.reductCount();
// 生成訂單
createOrder();
}
這次我們使用 synchronized 關鍵字給方法加了把“鎖”,理論上應該不會產生超賣現象了吧。
經實驗,仍然產生了超賣現象。
因為雖然方法被鎖住了,可是@Transactional 注解并沒有及時的提交事務,導致庫存沒有及時扣減為0,因此還是超賣了。
3.3 正確使用事務的代碼實現
@Autowired
private PlatformTransactionManager platformTransactionManager;
@Autowired
private TransactionDefinition transactionDefinition;
// @Transactional(rollbackFor = Exception.class)
public synchronized void buy() {
// 開啟事務
TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
try {
// 查看是商品否有庫存
Integer count = getProductCount();
if(count <= 0) {
throw new RuntimeException("庫存為 0");
}
// 減庫存
productRepository.reductCount();
// 生成訂單
createOrder();
// 事務提交
platformTransactionManager.commit(transactionStatus);
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
// 事務回滾
platformTransactionManager.rollback(transactionStatus);
}
}
這次我們不使用@Transactional 注解管理事務了,改為手動管理事務。
經實驗,解決了超賣現象。
4. 綜述
今天聊了一下 Springboot在有鎖的情況下如何正確使用事務,希望可以對大家的工作有所幫助。
到此這篇關于Springboot在有鎖的情況下如何正確使用事務的文章就介紹到這了,更多相關Springboot使用事務內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring boot與redis 實現session共享教程
這篇文章主要介紹了spring boot與redis 實現session共享教程,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-04-04

