国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站制作怎樣做背景贛州seo唐三

網(wǎng)站制作怎樣做背景,贛州seo唐三,廣州微信網(wǎng)站建設(shè)效果,網(wǎng)站系統(tǒng)分析的步驟有哪些分布式鎖mysql實現(xiàn)方式 方式1:唯一索引 創(chuàng)建鎖表,內(nèi)部存在字段表示資源名及資源描述,同一資源名使用數(shù)據(jù)庫唯一性限制。多個進(jìn)程同時往數(shù)據(jù)庫鎖表中寫入對某個資源的占有記錄,當(dāng)某個進(jìn)程成功寫入時則表示其獲取鎖成功其他進(jìn)程由于…

分布式鎖mysql實現(xiàn)方式
方式1:唯一索引

  • 創(chuàng)建鎖表,內(nèi)部存在字段表示資源名及資源描述,同一資源名使用數(shù)據(jù)庫唯一性限制。
  • 多個進(jìn)程同時往數(shù)據(jù)庫鎖表中寫入對某個資源的占有記錄,當(dāng)某個進(jìn)程成功寫入時則表示其獲取鎖成功
  • 其他進(jìn)程由于資源字段唯一性限制插入失敗陷入自旋并且失敗重試。
  • 當(dāng)執(zhí)行完業(yè)務(wù)后持有該鎖的進(jìn)程則刪除該表內(nèi)的記錄,此時回到步驟一。
    在這里插入圖片描述
    表數(shù)據(jù)
create table `database_lock`(`id` BIGINT NOT NULL AUTO_INCREMENT,`resource` INT NOT NULL COMMENT '鎖資源',`description` varchar(1024) NOT NULL DEFAULT "" COMMENT '描述',PRIMARY KEY (`id`),UNIQUE KEY `resource` (`resource`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='數(shù)據(jù)庫分布式鎖表';

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/distribute_lock?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
user=root
password=123456
  • PropertiesReader
@Slf4j
public class PropertiesReader {// Properties緩存文件private static final Map<String, Properties> propertiesCache = new HashMap<String, Properties>();public static Properties getProperties(String propertiesName) throws IOException {if (propertiesCache.containsKey(propertiesName)) {return propertiesCache.get(propertiesName);}loadProperties(propertiesName);return propertiesCache.get(propertiesName);}private synchronized static void loadProperties(String propertiesName) throws IOException {FileReader fileReader = null;try {// 創(chuàng)建Properties集合類Properties pro = new Properties();// 獲取src路徑下的文件--->ClassLoader類加載器ClassLoader classLoader = PropertiesReader.class.getClassLoader();URL resource = classLoader.getResource(propertiesName);// 獲取配置路徑String path = resource.getPath();// 讀取文件fileReader = new FileReader(path);// 加載文件pro.load(fileReader);// 初始化propertiesCache.put(propertiesName, pro);} catch (IOException e) {log.error("讀取Properties文件失敗,Properties名為:" + propertiesName);throw e;} finally {try {if (fileReader != null) {fileReader.close();}} catch (IOException e) {log.error("fileReader關(guān)閉失敗!", e);}}}
}
  • JDBCUtils
@Slf4j
public class JDBCUtils {private static String url;private static String user;private static String password;static {//讀取文件,獲取值try {Properties properties = PropertiesReader.getProperties("db.properties");url = properties.getProperty("url");user = properties.getProperty("user");password = properties.getProperty("password");String driver = properties.getProperty("driver");//4.注冊驅(qū)動Class.forName(driver);} catch (IOException | ClassNotFoundException e) {log.error("初始化jdbc連接失敗!", e);}}/*** 獲取連接* @return 連接對象*/public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}/*** 釋放資源* @param rs* @param st* @param conn*/public static void close(ResultSet rs, Statement st, Connection conn) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (st != null) {try {st.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}
}

數(shù)據(jù)庫操作類

/*** MySQL 鎖操作類(加鎖+釋放鎖)*/
@Slf4j
public class MySQLDistributedLockService {private static Connection connection;private static Statement statement;private static ResultSet resultSet;static{try {connection = JDBCUtils.getConnection();statement = connection.createStatement();resultSet = null;} catch (SQLException e) {log.error("數(shù)據(jù)庫連接失敗!");}}/*** 鎖表 - 獲取鎖* @param resource      資源* @param description   鎖描述* @return  是否操作成功*/public static boolean tryLock(int resource,String description){String sql = "insert into database_lock (resource,description) values (" + resource + ", '" + description + "');";//獲取數(shù)據(jù)庫連接try {int stat = statement.executeUpdate(sql);return stat == 1;} catch (SQLException e) {return false;}}/*** 鎖表-釋放鎖* @return*/public static boolean releaseLock(int resource) throws SQLException {String sql = "delete from database_lock where resource = " + resource;//獲取數(shù)據(jù)庫連接int stat = statement.executeUpdate(sql);return stat == 1;}/*** 關(guān)閉連接*/public static void close(){log.info("當(dāng)前線程: " + ManagementFactory.getRuntimeMXBean().getName().split("@")[0] +",關(guān)閉了數(shù)據(jù)庫連接!");JDBCUtils.close(resultSet,statement,connection);}
}

LockTable

/*** mysql分布式鎖*      執(zhí)行流程: 多進(jìn)程搶占數(shù)據(jù)庫某個資源,然后執(zhí)行業(yè)務(wù),執(zhí)行完釋放資源*      鎖機(jī)制: 單一進(jìn)程獲取鎖時,則其他進(jìn)程提交失敗*/
@Slf4j
public class LockTable extends Thread {@Overridepublic void run() {super.run();//獲取Java虛擬機(jī)的進(jìn)程IDString pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];try{while(true){log.info("當(dāng)前進(jìn)程PID:" + pid + ",嘗試獲取鎖資源!");if(MySQLDistributedLockService.tryLock(1,"測試鎖")){log.info("當(dāng)前進(jìn)程PID:" + pid + ",獲取鎖資源成功!");//sleep模擬業(yè)務(wù)處理過程log.info("開始處理業(yè)務(wù)!");Thread.sleep(10*1000);log.info("業(yè)務(wù)處理完成!");MySQLDistributedLockService.releaseLock(1);log.info("當(dāng)前進(jìn)程PID: " + pid + ",釋放了鎖資源!");break;}else{log.info("當(dāng)前進(jìn)程PID: " + pid + ",獲取鎖資源失敗!");Thread.sleep(2000);}}}catch (Exception e){log.error("搶占鎖發(fā)生錯誤!",e);}finally {MySQLDistributedLockService.close();}}// 程序入口public static void main(String[] args) {new LockTable().start();}
}

測試
運(yùn)行時開啟并行執(zhí)行選項,每次運(yùn)行三個或三個以上進(jìn)程. Allow parallel run 運(yùn)行并行執(zhí)行
image.png
image.png
注意事項:

  • 該鎖為非阻塞的
  • 當(dāng)某進(jìn)程持有鎖并且掛死時候會造成資源一直不釋放的情況,造成死鎖,因此需要維護(hù)一個定時清理任務(wù)去清理持有過久的鎖
  • 要注意數(shù)據(jù)庫的單點問題,最好設(shè)置備庫,進(jìn)一步提高可靠性
  • 該鎖為非可重入鎖,如果要設(shè)置成可重入鎖需要添加數(shù)據(jù)庫字段記錄持有該鎖的設(shè)備信息以及加鎖次數(shù)

方式二:基于樂觀鎖

  • 每次執(zhí)行業(yè)務(wù)前首先進(jìn)行數(shù)據(jù)庫查詢,查詢當(dāng)前的需要修改的資源值(或版本號)。
  • 進(jìn)行資源的修改操作,并且修改前進(jìn)行資源(或版本號)的比對操作,比較此時數(shù)據(jù)庫中的值是否和上一步查詢結(jié)果相同。
  • 查詢結(jié)果相同則修改對應(yīng)資源值,不同則回到第一步。
    image.png

例子:數(shù)據(jù)庫中設(shè)定某商品基本信息(名為外科口罩,數(shù)量為10),多進(jìn)程對該商品進(jìn)行搶購,當(dāng)商品數(shù)量為0時結(jié)束搶購。
在這里插入圖片描述
代碼實現(xiàn)

    /*** 樂觀鎖-獲取資源* @param id 資源ID* @return result*/public static ResultSet getGoodCount(int id) throws SQLException {String sql = "select  * from  database_lock_2 where id = " + id;//查詢數(shù)據(jù)resultSet = statement.executeQuery(sql);return resultSet;}/*** 樂觀鎖-修改資源* @param id        資源ID* @param goodCount 資源* @return  修改狀態(tài)*/public static boolean setGoodCount(int id, int goodCount) throws SQLException {String sql = "update database_lock_2 set good_count = good_count - 1 where id =" + id +"  and good_count = " + goodCount;int stat = statement.executeUpdate(sql);return stat == 1;}/*** 樂觀鎖-開啟事務(wù)自動提交*/public static void AutoCommit(){try {connection.setAutoCommit(true);} catch (SQLException e) {log.error("開啟自動提交!",e);}}

OptimisticLock測試類

/*** mysql分布式鎖-樂觀鎖*  執(zhí)行流程: 多進(jìn)程搶購?fù)簧唐?#xff0c;每次搶購成功商品數(shù)量-1,商品數(shù)據(jù)量為0時退出*  鎖機(jī)制: 單一進(jìn)程獲取鎖時,則其他進(jìn)程提交失敗*/
@Slf4j
public class OptimisticLock extends Thread{@Overridepublic void run() {super.run();String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];ResultSet resultSet = null;String goodName = null;int goodCount = 0;try {while(true){log.info("當(dāng)前線程:" + pid + ",開始搶購商品!");//獲取當(dāng)前商品信息resultSet = MySQLDistributedLockService.getGoodCount(1);while (resultSet.next()){goodName = resultSet.getString("good_name");goodCount = resultSet.getInt("good_count");}log.info("獲取庫存成功,當(dāng)前商品名為:" + goodName + ",當(dāng)前庫存剩余量為:" + goodCount);//模擬執(zhí)行業(yè)務(wù)操作Thread.sleep(2*3000);if(0 == goodCount){log.info("搶購失敗,當(dāng)前庫存為0! ");break;}//修改庫存信息,庫存量-1if(MySQLDistributedLockService.setGoodCount(1,goodCount)){log.info("當(dāng)前線程:" + pid + " 搶購商品:" + goodName + "成功,剩余庫存為:" + (goodCount -1));//模擬延遲,防止鎖每次被同一進(jìn)程獲取Thread.sleep(2 * 1000);}else{log.error("搶購商品:" + goodName +"失敗,商品數(shù)量已被修改");}}}catch (Exception e){log.error("搶購商品發(fā)生錯誤!",e);}finally {if(resultSet != null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();log.error("關(guān)閉Result失敗!" , e);}}MySQLDistributedLockService.close();}}public static void main(String[] args) {new OptimisticLock().start();}
}

代碼測試
開啟三個進(jìn)程,查看執(zhí)行情況
image.png
image.png
image.png
注意事項:

  • 該鎖為非阻塞的
  • 該鎖對于業(yè)務(wù)具有侵入式,如果設(shè)置版本號校驗則增加的額外的字段,增加了數(shù)據(jù)庫冗余
  • 當(dāng)并發(fā)量過高時會有大量請求訪問數(shù)據(jù)庫的某行記錄,對數(shù)據(jù)庫造成很大的寫壓力
  • 因此樂觀鎖適用于并發(fā)量不高,并且寫操作不頻繁的場景

方式三:悲觀鎖實現(xiàn)方式(利用事務(wù)加上行/表鎖)
在這里插入圖片描述
實現(xiàn)思路

  • 關(guān)閉jdbc連接自動commit屬性
  • 每次執(zhí)行業(yè)務(wù)前先使用查詢語句后接for update表示鎖定該行數(shù)據(jù)(注意查詢條件如果未命中主鍵或索引,此時將會從行鎖變?yōu)楸礞i)
  • 執(zhí)行業(yè)務(wù)流程修改表資源
  • 執(zhí)行commit操作

代碼實現(xiàn)
MySQLDistributedLockService

/*** 悲觀鎖-獲取資源* @param id 資源ID* @return result*/public static ResultSet getGoodCount2(int id) throws SQLException {String sql = "select  * from  database_lock_2 where id = " + id + "for update";//查詢數(shù)據(jù)resultSet = statement.executeQuery(sql);return resultSet;}/*** 悲觀鎖-修改資源* @param id        資源ID* @return  修改狀態(tài)*/public static boolean setGoodCount2(int id) throws SQLException {String sql = "update database_lock_2 set good_count = good_count - 1 where id =" + id;int stat = statement.executeUpdate(sql);return stat == 1;}/*** 悲觀鎖-關(guān)閉事務(wù)自動提交*/public static void closeAutoCommit(){try {connection.setAutoCommit(false);} catch (SQLException e) {log.error("關(guān)閉自動提交失敗!",e);}}/*** 悲觀鎖-提交事務(wù)*/public static void commit(String pid,String goodName,int goodCount) throws SQLException {connection.commit();log.info("當(dāng)前線程:" + pid + "搶購商品: " + goodName + "成功,剩余庫存為:" + (goodCount-1));}/*** 悲觀鎖-回滾*/public static void rollBack() throws SQLException {connection.rollback();}

PessimisticLock

/*** mysql 分布式鎖-悲觀鎖*     執(zhí)行流程:多個進(jìn)程搶占同一個商品,執(zhí)行業(yè)務(wù)完畢則通過connection.commit() 釋放鎖*     鎖機(jī)制:單一進(jìn)程獲取鎖時,則其他進(jìn)程將阻塞等待*/
@Slf4j
public class PessimisticLock extends Thread {@Overridepublic void run() {super.run();ResultSet resultSet = null;String goodName = null;int goodCount = 0;String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];//關(guān)閉自動提交MySQLDistributedLockService.closeAutoCommit();try{while(true){log.info("當(dāng)前線程:" + pid + "");//獲取庫存resultSet = MySQLDistributedLockService.getGoodCount2(1);while (resultSet.next()) {goodName = resultSet.getString("good_name");goodCount = resultSet.getInt("good_count");}log.info("獲取庫存成功,當(dāng)前商品名稱為:" + goodName + ",當(dāng)前庫存剩余量為:" + goodCount);// 模擬執(zhí)行業(yè)務(wù)事件Thread.sleep(2 * 1000);if (0 == goodCount) {log.info("搶購失敗,當(dāng)前庫存為0!");break;}// 搶購商品if (MySQLDistributedLockService.setGoodCount2(1)) {// 模擬延時,防止鎖每次被同一進(jìn)程獲取MySQLDistributedLockService.commit(pid, goodName, goodCount);Thread.sleep(2 * 1000);} else {log.error("搶購商品:" + goodName + "失敗!");}}}catch (Exception e){//搶購失敗log.error("搶購商品發(fā)生錯誤!",e);try {MySQLDistributedLockService.rollBack();} catch (SQLException ex) {log.error("回滾失敗! ",e);}}finally {if(resultSet != null){try {resultSet.close();} catch (SQLException e) {log.error("Result關(guān)閉失敗!",e);}}MySQLDistributedLockService.close();}}public static void main(String[] args) {new PessimisticLock().start();}
}

測試結(jié)果
image.png
image.png
image.png
注意事項:

  • 該鎖為阻塞鎖
  • 每次請求存在額外加鎖的開銷
  • 在并發(fā)量很高的情況下會造成系統(tǒng)中存在大量阻塞的請求,影響系統(tǒng)的可用性
  • 因此悲觀鎖適用于并發(fā)量不高,讀操作不頻繁的寫場景

總結(jié):

  • 在實際使用中,由于受到性能以及穩(wěn)定性約束,對于關(guān)系型數(shù)據(jù)庫實現(xiàn)的分布式鎖一般很少被用到。但是對于一些并發(fā)量不高、系統(tǒng)僅提供給內(nèi)部人員使用的單一業(yè)務(wù)場景可以考慮使用關(guān)系型數(shù)據(jù)庫分布式鎖,因為其復(fù)雜度較低,可靠性也能夠得到保證。
http://aloenet.com.cn/news/30591.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)公司相關(guān)資質(zhì)精準(zhǔn)客源app
  • 做百度網(wǎng)上搜索引擎推廣最好網(wǎng)站杭州seo網(wǎng)站排名優(yōu)化
  • 攝影網(wǎng)站建設(shè)內(nèi)容網(wǎng)站運(yùn)營一個月多少錢
  • 怎么做網(wǎng)站多少錢蘇州網(wǎng)站制作推廣
  • 做網(wǎng)站劃算還是做app劃算營銷型網(wǎng)站和普通網(wǎng)站
  • 做模版網(wǎng)站打開百度網(wǎng)站首頁
  • 優(yōu)化網(wǎng)站哪家好競價排名是按照什么來計費(fèi)的
  • 視頻網(wǎng)站seo實戰(zhàn)免費(fèi)私人網(wǎng)站建設(shè)軟件
  • 中山建設(shè)監(jiān)理有限公司 網(wǎng)站如何提高網(wǎng)站的搜索排名
  • wordpress上傳函數(shù)四川seo哪里有
  • 很好用的炫酷WordPress主題上海seo顧問
  • dede新聞網(wǎng)站源碼營銷課程培訓(xùn)視頻
  • 晉州做網(wǎng)站響應(yīng)式模版移動優(yōu)化
  • 建材公司網(wǎng)站建設(shè)方案點擊器 百度網(wǎng)盤
  • 深圳官方網(wǎng)站設(shè)計長沙網(wǎng)站策劃
  • 太原營銷網(wǎng)站建設(shè)制作平臺網(wǎng)站監(jiān)測
  • 學(xué)網(wǎng)站開發(fā)培訓(xùn)班seo為什么要進(jìn)行外部優(yōu)化
  • 網(wǎng)站建設(shè)源代碼上傳百度網(wǎng)頁怎么制作
  • 企業(yè)網(wǎng)站制作簡介bt螞蟻
  • 深圳網(wǎng)絡(luò)公司做網(wǎng)站臺州網(wǎng)站seo
  • 一對一直播軟件開發(fā)夫唯老師seo
  • 購物網(wǎng)站最重要的功能我要登錄百度
  • 保定哪做網(wǎng)站好企業(yè)查詢信息平臺
  • 做網(wǎng)站切圖網(wǎng)址怎么申請注冊
  • 黃山做網(wǎng)站公司關(guān)鍵詞搜索神器
  • 建網(wǎng)站比較靠譜的公司新媒體營銷推廣方案
  • 泰安網(wǎng)站制作服務(wù)2000元代理微信朋友圈廣告
  • 更改wordpress主題百度關(guān)鍵詞優(yōu)化多久上首頁
  • 專門做二手書網(wǎng)站或app百度云搜索引擎入口網(wǎng)盤搜索神器
  • 國外做燈的網(wǎng)站市場推廣方案