摘要:最近在項目上遇到了一個同一賬號多終端或者說多用戶同時登錄導致的重復問題。修改后的偽代碼如下同一賬號不能同時登錄用戶不存在當有兩個線程進入到,第一個線程會修改版本號并插入,而第二個線程則會因為版本號不一致,拋出異常。
最近在項目上遇到了一個同一賬號多終端(或者說多用戶)同時登錄導致的token重復問題。可以在瀏覽器相應地做一些防止表單重復提交的操作,比如登錄按鈕點擊一次后變成不可點擊的狀態,等待服務器的響應之后再恢復成點擊狀態。不過這也并不能解決同一賬號多終端登錄的問題。
https://github.com/bluesnail9...
項目中的偽代碼如下:User user = getUser(username,password); if(null != user) { String token = findToken(user); if(null != token) { user.deleteToken(user); token = null; } if(null == token){ user.insertNewToken(user); } }else { throw new Exception("用戶不存在"); }想一想:
為什么會出現token重復的問題?因為同一賬號多用戶(或者多終端)同時登錄時都進入到了if(null == token)這個語句,所以就向數據庫中插入了多個token,但是按道理,一個賬號,只能對應一個token。
那如何解決這個問題呢?(1)我開始想到的是做一個同步,用synchronized同步語句塊。
User user = getUser(username,password); if(null != user) { //使用synchronized做同步 synchronized(username.intern()){ String token = findToken(user); if(null != token) { user.deleteToken(user); token = null; } if(null == token){ user.insertNewToken(user); } } }else { throw new Exception("用戶不存在"); }
synchronized括號里的內容應該寫什么呢?User實例(對象)?每個線程的User實例都是不一樣的。username變量?試了不起作用。username并不是在編譯期就可知的,而是在運行期從瀏覽器傳遞到后臺。修改成username.intern()是可以成功的,intern()方法會在常量池中查找和創建字符串。
(2)使用鎖ReentrantLock做同步
//定義鎖 private ReentrantLock lock = new ReentrantLock(); User user = getUser(username,password); if(null != user) { try{ //獲取鎖 lock.lock(); String token = findToken(user); if(null != token) { user.deleteToken(user); token = null; } if(null == token){ user.insertNewToken(user); } }catch(Exception e) { e.printStackTrace(); }finally { //釋放鎖 lock.unlock(); } }
注意:定義一個私有公共的ReentrantLock,獲取鎖是調用lock()方法,釋放鎖調用unlock()方法。如果對于每一個線程都需要加鎖和釋放鎖,性能會比較低。
(3)使用數據庫的樂觀鎖實現。
在用戶表上添加一個表示版本的字段。每次用戶登錄添加token時,都需要進行版本的比較,只有版本一致時,才進行添加token操作。
修改后的偽代碼如下:
User user = getUser(username,password); if(null != user) { String token = findToken(user); if(null != token) { user.deleteToken(user); token = null; } if(null == token){ int version = getUserVersion(user.getId()); if(version == user.getVersion()) { updateVersion(version+1,User); user.insertNewToken(user); }else { throw new Exception("同一賬號不能同時登錄"); } } }else { throw new Exception("用戶不存在"); }
當有兩個線程進入到if(null == token),第一個線程會修改版本號并插入token,而第二個線程則會因為版本號不一致,拋出異常。
參考文章:
https://blog.csdn.net/u014653...
https://blog.csdn.net/antony9...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/71246.html
摘要:生成在控制臺中繼續輸入,生成密鑰。將文件夾中的公鑰添加到管理平臺中,在的個人賬戶的設置中找到如下界面。添加到暫存區后,我們會發現這兩個文件的顏色變為了綠色。在熟悉以后,可能會發現有更加簡潔快速的提交修改的使用方法。在開發項目時,往往不是一個人進行項目開發,而通常是以團隊的形式進行開發一個新功能,那項目開發是如何進行多人高效協作的呢?在不同的開發階段,我們遇到各種各樣的問題,當遇到這些問題時,...
摘要:微信網頁授權,基于適配方案,開發的微信授權方案。項目地址又又又一次來寫微信網頁授權,一年前寫過的微信授權解決方案。 vue微信網頁授權,基于vue-cli3.0+webpack 4+vant ui + sass+ rem適配方案+axios,開發的微信授權方案。項目地址:vue-wechat-auth 又又又一次來寫微信網頁授權,一年前寫過的 [vue 微信授權解決方案]。 參考了[v...
摘要:針對這種情況,友戶通特定開發了聯邦用戶中心來支持企業的自有用戶中心。友戶通支持通過協議使用企業內部的支持協議的用戶中心賬號進行登錄。友戶通目前支持標準協議以及友戶通自定義協議可供企業集成。 友戶通做用友云的用戶系統也一年多了,經常聽實施、售前等說要私有化部署友戶通,原因無非是企業的考慮到用戶安全性和單一用戶賬號的需求。但由于用戶管理的復雜性,友戶通部署與維護并不容易,因此經常糾結在用戶...
摘要:為用戶提供授權以允許用戶操作非公開資源,有很多種方式。具體的代碼根據不同的授權方案而有所不同。使用授權原理利用來驗證用戶,有兩種機制實現。使用來實現用戶授權主要用于簽發如果有將異步的簽名。注意這里的與之前用于簽發的應該是同一個。 在很多應用中,我們都需要向服務端提供自己的身份憑證來獲得訪問一些非公開資源的授權。比如在一個博客平臺,我們要修改自己的博客,那么服務端要求我們能夠證明 我是...
摘要:本人長期出售超大量微博數據旅游網站評論數據,并提供各種指定數據爬取服務,。如果用戶傳入偽造的,則新浪微博會返回一個錯誤。 PS:(本人長期出售超大量微博數據、旅游網站評論數據,并提供各種指定數據爬取服務,Message to YuboonaZhang@Yahoo.com。由于微博接口更新后限制增大,這個代碼已經不能用來爬數據了。如果只是為了收集數據可以咨詢我的郵箱,如果是為了學習爬蟲,...
閱讀 2841·2021-09-10 10:50
閱讀 2197·2019-08-29 16:06
閱讀 3200·2019-08-29 11:02
閱讀 1102·2019-08-26 14:04
閱讀 2813·2019-08-26 13:24
閱讀 2306·2019-08-26 12:16
閱讀 554·2019-08-26 10:29
閱讀 3102·2019-08-23 18:33