當前位置:編程學習大全網 - 編程語言 - Java如何實現對Mysql數據庫的行鎖(java代碼實現數據庫鎖)

Java如何實現對Mysql數據庫的行鎖(java代碼實現數據庫鎖)

下面通過壹個例子來說明

場景如下:

用戶賬戶有余額,當發生交易時,需要實時更新余額。這裏如果發生並發問題,那麽會造成用戶余額和實際交易的不壹致,這對公司和客戶來說都是很危險的。

那麽如何避免:

網上查了下,有以下兩種方法:

1、使用悲觀鎖

當需要變更余額時,通過代碼在事務中對當前需要更新的記錄設置forupdate行鎖,然後開始正常的查詢和更新操作

這樣,其他的事務只能等待該事務完成後方可操作

當然要特別註意,如果使用了Spring的事務註解,需要配置壹下:

class="org..jdbc.datasource."

在指定代碼處添加事務註解

@

@Override

publicboolean(LonguserId,BigDecimalamount)

throws{

longtime=System.();

//獲取對記錄的鎖定

UserBalancebalance=.getLock(userId);

LOGGER.info("[lock]start.time:{}",time);

if(null==balance){

thrownew(

.ERRORCODE_BALANCE_NOTEXIST,"userbalanceisnotexist");

}

booleanresult=.(balance,amount);

longtimeEnd=System.();

LOGGER.info("[lock]end.time:{}",timeEnd);

returnresult;

}

MyBatis中的鎖定方式,實際測試該方法確實可以有效控制,不過在大並發量的情況下,可能會有性能問題吧

select*fromuser_balancewhereid=#{id,jdbcType=BIGINT}forupdate;

]]

2、使用樂觀鎖

這個方法也同樣可以解決場景中描述的問題(我認為比較適合並不頻繁的操作):

設計表的時候增加壹個version(版本控制字段),每次需要更新余額的時候,先獲取對象,update的時候根據version和id為條件去更新,如果更新回來的數量為0,說明version已經變更

需要重復壹次更新操作,如下:sql腳本

updateuser_balancesetBalance=#{balance,jdbcType=DECIMAL},Version=Version1whereId=#{id,jdbcType=BIGINT}andVersion=#{version,jdbcType=BIGINT}

這是壹種不使用數據庫鎖的方法,解決方式也很巧妙。當然,在大量並發的情況下,壹次扣款需要重復多次的操作才能成功,還是有不足之處的。不知道還有沒有更好的方法。

  • 上一篇:劍俠情緣1997攻略
  • 下一篇:壹個有趣的問題,linux 和 windows 的區別
  • copyright 2024編程學習大全網