1. 程式人生 > >Java 高併發專案筆記

Java 高併發專案筆記

maven 配置與安裝

下載maven 檔案
解壓之後,將檔案移動到\Applications資料夾內

使用cd ~ 進入根目錄資料夾 用ls -a列出資料夾內的所有檔案,找到一個名稱為.bash_profile的檔案,開啟該檔案來配置環境變數

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
export MAVEN_HOME=/Applications/apache-maven-3.5.4
export PATH=$PATH:$MAVEN_HOME/bin

配置完之後 新增/調整
商家 -> 庫存
<-
發貨/核賬source .bash_profile

編譯一下 然後在命令列之中用mvn - v來檢查一下是否安裝成功

配置環境變數
注意預設的cd ~可能不是根目錄而是當前使用者的目錄 User\auguskong\

mvn archetype:generate -DgroupId=org.seckill -DartifactId=seckill -DarchetypeArtifactId=maven-archetype-webapp

修改servlet版本為3.1

秒殺系統業務分析

 新增(+)/調整(+/-)

商家 -> 庫存
<-
發貨/核賬

 付款(-)/退貨(+)  

使用者 -> 庫存
<-
秒殺/預售

秒殺業務的核心在於庫存的處理

使用者:

【減庫存 + 記錄購買明細 】
|
【完整事務】 誰 + 時間/有效期 + 付款/發貨資訊
|
【資料落地】

為什麼需要事務? -> 事務機制依然是最可靠的資料落地方案
考慮一下情景:
減庫存沒有記錄購買明細?
記錄了購買明細但是沒有減庫存?
出現超賣/少買?

秒殺系統難點分析 -> 競爭
同一時間多個使用者購買

事務 + 行級鎖

Start Transaction
Update 庫存數量
Insert 購買明細
Commit

update table set num = num - 1 where id = 10 and num > 1

資料庫設計與編碼

資料庫路徑設定
export PATH=$PATH:/usr/local/mysql/bin/

BUG!! 中英文輸入法的問號意義不一樣 必須使用英文的問號!!

使用 mysql -u root -p 來開啟mysql面板
show create table seckill\G 檢視如何建立這個表

手寫DDL
記錄每次上線的DDL修改
--上線V1.1
ALTER TABLE seckill
DROP INDEX idx_create_time,
add index idx_c_s(start_time, create_time);

DAO實體和介面編碼

TABLE -> ENTITY 表對應java類 列對應java類當中的屬性

Command + N 開啟generate 可以讓編譯器自動生成getter 和 setter 方法

MyBatis 對映

資料庫 -> 對映 -> 物件

為什麼可以過濾重複? 聯合主鍵是??
聯合主鍵裡面有電話號碼,由主鍵不允許重複的特性保證了不存在兩個相同的電話號碼,可以防止一個使用者重複秒殺

4-3 基於MyBatis實現DAO理論
MyBatis, Hibernate, JDBC 都是做對映的工作 物件關係對映?

MyBatis 特點

需要提供引數 + SQL(SQL必須使用者來寫)

SQL寫在哪?

1.【推薦】XML當中
2.註解提供SQL (註解本身還是Java原始碼 且SQL存在拼接時很麻煩) @SQL Java 1.5之後提供
註解的缺點: 註解本質上也是Java原始碼,需要編譯之後才能執行 複雜拼接邏輯會很複雜

如何實現DAO介面?
1.【推薦】Mapper 自動實現DAO介面 這樣可以只關注於SQL介面,
2.API程式設計方式實現DAO介面

寫三個SQL

自己控制SQL

MyBatis整合Spring的過程

目的:
使用更少的編碼: 原則是隻寫介面,不寫實現 (實現是MyBatis自動實現)
Seckill queryById(long id)
介面引數
名字代表行為
介面返回型別表示結果集
更少的配置:
* MyBatis 自動找到包名 減少了包名的程式碼
* 自動掃描配置檔案 減去配置維護成本

儲存足夠的靈活性:自己定製 SQL + 自由傳參

預設

DAO層單元測試編碼和問題排查

import org.junit 檔案包不存在的問題

//使用@Param 註解來告知MyBatis 相關引數的名字
List<Seckill> queryAll(@Param("offset") int offet, @Param("limit") int limit);

MyBatis和Spring的整合就在於配置檔案的設定

 public void insertSuccessKilled() {
        long id = 1001L;
        long phone = 13421234569L;
        int insertCount = successKilledDao.insertSuccessKilled(id, phone);
        System.out.println("insertCount= " + insertCount);
    }

報錯空指標異常
***

命令列命令:

ifconfig可以檢視本地IP地址
MySQL 8.0當中設定密碼的新語法 SET PASSWORD FOR 'jeffrey'@'localhost' = 'auth_string';
按兩次shift快速查詢project當中的檔案

bug log:

URL is not registered

mapper裡面筆誤 parameterType 改為resultType
mybatis config檔案裡面筆誤

確定mysql的版本是和本機版本相同 進入mysql命令列之後 輸入select version() 或 直接在進入時看初始載入資訊

資料庫連線失敗可能原因:

  1. jdbc.properties 配置錯誤:
    1. jdbc.driver: 注意check manual確保命令正確
    2. jdbc.url:
    3. username + password
  2. 未授權遠端訪問或沒有訪問許可權 需要通過SQL GRANT進行相關操作
  3. 專案未引入對應版本的驅動jar包,配置檔案的設定 mysql-connector-java-5.1.6-bin.jar

因為沒有設定時區而導致了bug, 這個有點扯淡了
jdbc.url=jdbc:mysql://localhost/seckill?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8

DAO層編碼
編寫介面
邏輯程式碼一行沒寫

有什麼好處?

DAO層演變為介面設計 + SQL編寫
程式碼和SQL的分離
DAO拼接等邏輯在Service層完成 邏輯放在Service層當中
對遠端儲存系統做操作的 放在DAO層


秒殺Service介面設計

站在使用者的角度設計介面
配置是一次性工作