如果數(shù)據(jù)庫保存的就是明碼,可以忽略大小寫作匹配。
在網(wǎng)站建設(shè)、做網(wǎng)站中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營銷成為有效果、有回報(bào)的無錫營銷推廣。成都創(chuàng)新互聯(lián)專業(yè)成都網(wǎng)站建設(shè)十載了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。
如果保存的是密鑰,就是經(jīng)過加密之后的密碼,就要和加密之前的密碼一致。
下面通過一個(gè)例子來說明
場景如下:
用戶賬戶有余額,當(dāng)發(fā)生交易時(shí),需要實(shí)時(shí)更新余額。這里如果發(fā)生并發(fā)問題,那么會造成用戶余額和實(shí)際交易的不一致,這對公司和客戶來說都是很危險(xiǎn)的。
那么如何避免:
網(wǎng)上查了下,有以下兩種方法:
1、使用悲觀鎖
當(dāng)需要變更余額時(shí),通過代碼在事務(wù)中對當(dāng)前需要更新的記錄設(shè)置for update行鎖,然后開始正常的查詢和更新操作
這樣,其他的事務(wù)只能等待該事務(wù)完成后方可操作
當(dāng)然要特別注意,如果使用了Spring的事務(wù)注解,需要配置一下:
!-- (事務(wù)管理)transaction manager, use JtaTransactionManager for global tx --
bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="dataSource" ref="dataSource" /
/bean
!-- 使用annotation定義事務(wù) --
tx:annotation-driven transaction-manager="transactionManager" /
在指定代碼處添加事務(wù)注解
@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中的鎖定方式,實(shí)際測試該方法確實(shí)可以有效控制,不過在大并發(fā)量的情況下,可能會有性能問題吧
select id="getLock" resultMap="BaseResultMap" parameterType="java.lang.Long"
![CDATA[
select * from user_balance where id=#{id,jdbcType=BIGINT} for update;
]]
/select
2、使用樂觀鎖
這個(gè)方法也同樣可以解決場景中描述的問題(我認(rèn)為比較適合并不頻繁的操作):
設(shè)計(jì)表的時(shí)候增加一個(gè)version(版本控制字段),每次需要更新余額的時(shí)候,先獲取對象,update的時(shí)候根據(jù)version和id為條件去更新,如果更新回來的數(shù)量為0,說明version已經(jīng)變更
需要重復(fù)一次更新操作,如下:sql腳本
update user_balance set Balance = #{balance,jdbcType=DECIMAL},Version = Version+1 where Id = #{id,jdbcType=BIGINT} and Version = #{version,jdbcType=BIGINT}
這是一種不使用數(shù)據(jù)庫鎖的方法,解決方式也很巧妙。當(dāng)然,在大量并發(fā)的情況下,一次扣款需要重復(fù)多次的操作才能成功,還是有不足之處的。不知道還有沒有更好的方法。
與java無關(guān),要用sql語句實(shí)現(xiàn)
前提目標(biāo)表要有索引,查詢要開啟事物,使用select * from tb with(updlock) where col = xxx將一行數(shù)據(jù)鎖住,其他連接不能再修改表