最近公司在作團購這塊的一個商品的促銷活動,在建立促銷的時候發現只能有一個用戶進行修改和編輯,若是其餘用戶操做同一個促銷活動就會出現數據不一致,這也就是咱們常常遇到的多人同時操做的問題,下面我將詳細介紹關於這塊咱們的解決方案java
出現數據不一致的現象一般分爲兩種:1.覆蓋更新 2.髒讀數據庫
關於這類問題通常會考慮到用數據庫鎖的機制來解決併發
數據庫鎖分爲樂觀鎖和悲觀鎖性能
樂觀鎖並不鎖住任何東西,而是在提交事務時檢查本身上次讀取這條記錄後,是否有其餘事務修改了這條記錄,若是沒有則提交,若是被修改了則回滾。若是併發的可能性並不大,那麼鎖定策略帶來的性能消耗是很是小的spa
與樂觀鎖相比,悲觀鎖則是一把真正的鎖了,它經過SQL語句「select for update」鎖住數據,這時若是其餘事務來更新時會等待,悲觀鎖會鎖住整張表,性能較低,致使其餘的事務不能訪問code
接下來對於這塊我採用的是樂觀鎖的方案,關於實現樂觀鎖有三種方式:
1.是爲數據表增長一個version字段,每次事務開始時,取出version,在提交事務時,檢查version是否有變化
若是沒有變化提交事務時將version + 1,SQL差很少是這樣:事務
UPDATE t_promotion set version = version + 1 where promotionid = ? and version = ?
2.是爲數據表增長一個時間戳字段,而後經過比較時間戳檢查該數據是否被其餘事務修改過。
3.是檢查對應的字段的值有沒有變化io
這裏採用第一種方式 ,第二種跟第一種很相似 第三種性能不高class
總結筆記原理
解決多人同時操做問題解決方案: 1.採用數據庫鎖的機制 樂觀鎖的實現方案: 就是在提交事務時檢查本身上次讀取這條記錄後,是否有其餘事務修改了這條記錄,若是沒有則提交,若是被修改了則回滾 通常有三種方式實現樂觀鎖: (1).是爲數據表增長一個version字段,每次事務開始時,取出version,在提交事務時,檢查version是否有變化 若是沒有變化提交事務時將version + 1,SQL差很少是這樣: UPDATE T_IRS_RESOURCE set version = version + 1 where resource_id = ? and version = ? (2).是爲數據表增長一個時間戳字段,而後經過比較時間戳檢查該數據是否被其餘事務修改過。 (3).是檢查對應的字段的值有沒有變化。 ibatis實現樂觀鎖解決方案的實現原理 使用數據版本(Version)記錄機制實現,這是樂觀鎖最經常使用的一種實現方式。何謂數據版本?即爲數據增長一個版本標識,通常是經過爲數據庫表增長一個數字類型的 「version」 字段來實現。當讀取數據時,將version字段的值一同讀出,數據每更新一次,對此version值加一,當咱們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的version值進行比對,若是數據庫表當前版本號與第一次取出來的version值相等,則予以更新,不然認爲是過時數據 舉例: 那麼爲了使用樂觀鎖,咱們首先修改t_goods表,增長一個version字段,數據默認version值爲1。 <update id="updateGoodsUseCAS" parameterType="Goods"> <![CDATA[ update t_goods set status=#{status},name=#{name},version=version+1 where id=#{id} and version=#{version} ]]> </update>