當前位置:首頁 » 編程語言 » java資料庫加鎖

java資料庫加鎖

發布時間: 2025-02-15 01:34:14

1. java如何實現對Mysql資料庫的行鎖

下面通過一個例子來說明
場景如下:
用戶賬戶有餘額,當發生交易時,需要實時更新余額。這里如果發生並發問題,那麼會造成用戶余額和實際交易的不一致,這對公司和客戶來說都是很危險的。
那麼如何避免:
網上查了下,有以下兩種方法:
1、使用悲觀鎖
當需要變更余額時,通過代碼在事務中對當前需要更新的記錄設置for update行鎖,然後開始正常的查詢和更新操作
這樣,其他的事務只能等待該事務完成後方可操作
當然要特別注意,如果使用了Spring的事務註解,需要配置一下:

<!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 使用annotation定義事務 -->
<tx:annotation-driven transaction-manager="transactionManager" />

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

@Transactional
@Override
public boolean increaseBalanceByLock(Long userId, BigDecimal amount)
throws ValidateException {
long time = System.currentTimeMillis();
//獲取對記錄的鎖定
UserBalance balance = userBalanceDao.getLock(userId);
LOGGER.info("[lock] start. time: {}", time);
if (null == balance) {
throw new ValidateException(
ValidateErrorCode.ERRORCODE_BALANCE_NOTEXIST,
"user balance is not exist");
}
boolean result = userBalanceDao.increaseBalanceByLock(balance, amount);
long timeEnd = System.currentTimeMillis();
LOGGER.info("[lock] end. time: {}", timeEnd);
return result;
}

MyBatis中的鎖定方式,實際測試該方法確實可以有效控制,不過在大並發量的情況下,可能會有性能問題吧
<select id="getLock" resultMap="BaseResultMap" parameterType="java.lang.Long">
<![CDATA[
select * from user_balance where id=#{id,jdbcType=BIGINT} for update;
]]>
</select>

2、使用樂觀鎖
這個方法也同樣可以解決場景中描述的問題(我認為比較適合並不頻繁的操作):
設計表的時候增加一個version(版本控制欄位),每次需要更新余額的時候,先獲取對象,update的時候根據version和id為條件去更新,如果更新回來的數量為0,說明version已經變更
需要重復一次更新操作,如下:sql腳本

update user_balance set Balance = #{balance,jdbcType=DECIMAL},Version = Version+1 where Id = #{id,jdbcType=BIGINT} and Version = #{version,jdbcType=BIGINT}

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

熱點內容
note3ftp 發布:2025-04-23 10:23:30 瀏覽:837
伺服器地址後面要加埠 發布:2025-04-23 10:14:42 瀏覽:866
安卓如何關閉自動管理 發布:2025-04-23 09:45:27 瀏覽:656
shell文件編程 發布:2025-04-23 09:41:43 瀏覽:12
安卓課程表源碼 發布:2025-04-23 09:41:39 瀏覽:950
黃金的腳本 發布:2025-04-23 09:30:16 瀏覽:696
線程池在什麼地方配置 發布:2025-04-23 09:24:29 瀏覽:698
怎樣實現同步更新資料庫資料庫數據 發布:2025-04-23 09:03:25 瀏覽:103
醫葯基金配置的是什麼板塊 發布:2025-04-23 09:02:35 瀏覽:310
php安裝odbc 發布:2025-04-23 09:01:54 瀏覽:616