继开 | 博客

热爱生活,努力学习,实现自己的价值


  • 短诗的序

  • 迷途自渡

  • 寒星三两

  • 林深见鹿

  • 记昨日书

  • 顾探往昔

Idea中几个好用的插件分享,持续更新

发表于 2022-01-21
字数统计: 173 字 | 阅读时长 ≈ 1 min

插件分享

阿里巴巴,代码检测工具
Alibaba Java Coding Guidelines

Mybatis 实现mapper 和对应类跳转,以及简单错误提示
Free Mybatis Plugin (Mybatis lite)

使用化简get,set 插件的不报错,必装
Lombok

vue文件查看,装上之后看前端文件,格式提示
Vue.js

安装方式

打开 IDEA,选择 File - Settings - Plugins - Browse repositories 后,输入 alibaba 选中 Alibaba Java Coding Guidelines,点击 Install。

一辈子很短,努力的做好两件事就好:
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。

Idea远程debug SpringBoot项目

发表于 2022-01-20
字数统计: 499 字 | 阅读时长 ≈ 2 min

本地

ide 工具栏中 Run —> Edit Configurations.

选择左侧 + 号,选择 Remote,

修改name,
修改Host地址localhost 到远程端 192.168.1.102,自己项目启动到那个地址就填那个
修改Post,也可用默认5005

根据jdk版本选择command line arguments for runing remote JVM ,默认5-8

点击Apply即可;

远端启动之后,点击debug运行即可

远程端

在远程服务启动的时候 运行SringBoot时 加上

1
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

例如:

1
java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 springboot-test-1.0-SNAPSHOT.jar

由此配置完成,可本地调试远程运行的代码了

注意:本地代码和远程服务器上的类文件相同

原理

Java 程序是运行在Java 虚拟机(JVM )上的,具有良好跨平台性,
因为Java程序统一以字节码的形式在JVM中运行,不同平台的虚拟机都统一使用这种相同的程序存储格式。
因为都是类字节码文件,只要本地代码和远程服务器上的类文件相同,两个JVM通过调试协议进行通信(例如通过插座在同一个端口进行通信),
另外需要注意的时,被调试的服务器需要开启调试模式,服务器端的代码和本地代码必须保持一致,则会造成断点无法进入的问题。

可能出现链接不通情况问题解决

1.检查服务器防火墙,有可能防火墙未开放

2.将 suspend=n 修改为 suspend=y 不启动远程调试,不启动项目,运行远端之后,再运行本地调试,就可以了

一辈子很短,努力的做好两件事就好:
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。

线上问题,事务互锁,不能操作数据库

发表于 2022-01-13
字数统计: 1,026 字 | 阅读时长 ≈ 5 min

线上问题,事务互锁,不能操作数据库

上线一个支付功能,由于用户量过大,需要频繁的获取未支付订单的所有状态
结果频繁报错

1
2
3
4
5
6
7
Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20, maxActive 20, creating 0, runningSqlCount 8 : SELECT  id,pay_code,yaoma,manager,manager_id,paid_cash_all,pay_name,pay_tel,pay_id,pay_bh,pay_datetime,pay_method,manually_add_user,manually_add_user_id,manually_add_datetime,pay_state,openid,le_shua_pay_state,paychanel_order_id,sign_type,out_trade_no,create_time,create_user,update_time,update_user  FROM my_payment_order 

WHERE (pay_state = ? AND out_trade_no IS NOT NULL)
runningSqlCount 5 : SELECT id,pay_code,yaoma,manager,manager_id,paid_cash_all,pay_name,pay_tel,pay_id,pay_bh,pay_datetime,pay_method,manually_add_user,manually_add_user_id,manually_add_datetime,pay_state,openid,le_shua_pay_state,paychanel_order_id,sign_type,out_trade_no,create_time,create_user,update_time,update_user FROM my_payment_order

WHERE (yaoma = ? AND pay_state = ?) ORDER BY pay_datetime ASC
runningSqlCount 6 : UPDATE my_payment_order SET pay_code=?,

一开始以为是数据库链接池不对,增大了链接池,结果不生效

后来查到原因是查询支付接口订单的时候只能单个订单查询,调用外部支付接口的支付订单信息

注意,此处开启了事务,但是订单很多,循环调用很多次外部接口,查询订单信息,若同时并发此处会造成事务死锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* 查询支付中的订单信息,查询乐刷中的订单信息,并且更新相关状态;
* @param list
* @return
*/
@Override
@DataSource(name = "DB1")
@Transactional(rollbackFor = Exception.class)
public List<myPaymentOrder> searchPayWaitingFromLeShua(List<myPaymentOrder> list) throws Exception{
for( myPaymentOrder myPaymentOrderOld:list){
String outTradeNo = myPaymentOrderOld.getOutTradeNo();
String terminalTrace = String.valueOf(myPaymentOrderOld.getPayCode());
//这里调用外部接口
String result= leShuaPayService.leShuaPayQuerypay(outTradeNo,terminalTrace);
JSONObject jsonObject = JSONObject.parseObject(result);
if(ObjectUtil.isNotEmpty(jsonObject)&&ObjectUtil.isNotEmpty(jsonObject.get("result_code"))){
String resultCode = String.valueOf(jsonObject.get("result_code"));
//支付订单成功 01
myPaymentOrderOld.setLeShuaPayState(resultCode);
if(resultCode.equals(LeShuaPayStateEnum.PAY_SUCCESS.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_SUCCESS.getCode());
}
//支付失败 02
if(resultCode.equals(LeShuaPayStateEnum.PAY_FAILURE.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_ERR.getCode());
}
//支付中 03
if(resultCode.equals(LeShuaPayStateEnum.PAY_WAITING.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_WAITING.getCode());
}
// 根据订单号查询,乐刷订单支付状态返回乐刷的支付状态,更新支付人信息,支付状态信息等
this.update(myPaymentOrderOld);
//根据订单的信息,修改订单详情的支付状态;
this.myPaymentOrderDetailsService.updateMyPaymentOrder(myPaymentOrderOld);
}
}
return list;
}

```
修改后

```java

@Override
@DataSource(name = "DB1")
@Transactional(rollbackFor = Exception.class)
public List<myPaymentOrder> searchPayWaitingFromLeShua() throws Exception {
//构造条件
LambdaQueryWrapper<myPaymentOrder> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(myPaymentOrder::getPayState,PayStateEnum.PAY_WAITING.getCode());
queryWrapper.isNotNull(myPaymentOrder::getOutTradeNo);
List<myPaymentOrder> list = this.list(queryWrapper);
for( myPaymentOrder myPaymentOrderOld:list){
String outTradeNo = myPaymentOrderOld.getOutTradeNo();
String terminalTrace = String.valueOf(myPaymentOrderOld.getPayCode());
String result= leShuaPayService.leShuaPayQuerypay(outTradeNo,terminalTrace);
JSONObject jsonObject = JSONObject.parseObject(result);
if(ObjectUtil.isNotEmpty(jsonObject)&&ObjectUtil.isNotEmpty(jsonObject.get("result_code"))){
String resultCode = String.valueOf(jsonObject.get("result_code"));
//支付订单成功 01
myPaymentOrderOld.setLeShuaPayState(resultCode);
if(resultCode.equals(LeShuaPayStateEnum.PAY_SUCCESS.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_SUCCESS.getCode());
}
//支付失败 02
if(resultCode.equals(LeShuaPayStateEnum.PAY_FAILURE.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_ERR.getCode());
}
//支付中 03
if(resultCode.equals(LeShuaPayStateEnum.PAY_WAITING.getCode())){
myPaymentOrderOld.setPayState(PayStateEnum.PAY_WAITING.getCode());
}
}
}
if(list.size()>0){
// 批量更新状态信息
this.updateBatchById(list);
this.myPaymentOrderDetailsService.updateMyPaymentOrderList(list);
}
return list;
}

更新前的单数据更新sql

1
2
3
4
5
<update id="updateMyPaymentOrder" parameterType="com.halfsky.my.modular.paymentorder.entity.myPaymentOrder" >
update my_payment_order_details
set pay_state = #{paramCondition.payState,jdbcType=INTEGER}
where pay_code = #{paramCondition.payCode,jdbcType=BIGINT}
</update>

更新后批量数据更新sql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 批量更新 -->
<update id="updateMyPaymentOrderList" parameterType="java.util.List">
update my_payment_order_details
<trim prefix="set" suffixOverrides=",">
<trim prefix="pay_state =case" suffix="end,">
<foreach collection="paramCondition" item="item" index="index">
when pay_code=#{item.payCode} then #{item.payState}
</foreach>
</trim>
</trim>
where pay_code in
<foreach collection="paramCondition" index="index" item="item" separator="," open="(" close=")">
#{item.payCode}
</foreach>
</update>

总结

单个方法中对多个表的数据修改,编辑,删除数据都要增加事务注解(@Transactional(rollbackFor = Exception.class))
在方法中尽可能的减少对数据库的占用时间,特别是需要调用外部接口之后的修改,建议批量修改,而不是单个修改。
多次的操纵单次修改,在并发量很大的情况下容易造成事务的互锁。

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

Windows子系统导入导出

发表于 2022-01-12
字数统计: 214 字 | 阅读时长 ≈ 1 min

windows子系统快速的备份,和恢复方法,这也是快速修改安装目录的方法

1.首先查看所有分发版本

1
wsl -l -v
1
2
NAME STATE VERSION
* Ubuntu-20.04 Running 2

2.导出分发版为tar文件到d盘

1
wsl --export Ubuntu d:\ubuntu.tar

3.注销当前分发版

1
wsl --unregister Ubuntu

4.重新导入并安装分发版在d:\ubuntu

1
wsl --import Ubuntu d:/ubuntu d:/ubuntu.tar --version 2

5.设置默认登陆用户为安装时用户名

1
Ubuntu config --default-user root

6.删除tar文件(可选)

1
del  d:/ubuntu.tar

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

2022-01-01-Linux Linux 命令终端提示符显示-Bash-4.2#解决方法

发表于 2022-01-01
字数统计: 208 字 | 阅读时长 ≈ 1 min

问题:在配置linux,突然发现root登录的CRT的终端提示符显示的是-bash-4.2# 而不是root@主机名 + 路径的显示方式。

原因是root在/root下面的几个配置文件丢失,丢失文件如下:
1、.bash_profile
2、.bashrc
以上这些文件是每个用户都必备的文件。
使用以下命令从主默认文件重新拷贝一份配置信息到/root目录下

1
2
cp /etc/skel/.bashrc /root/
cp /etc/skel/.bash_profile /root/

注销root,重新登录就可以恢复正常。

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

编写一个圣诞树

发表于 2021-12-30
字数统计: 404 字 | 阅读时长 ≈ 2 min

test.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
hell编写一个圣诞树
#创建时间2021-12-23
trap "tput reset; tput cnorm; exit" 2
clear
tput civis
lin=2
col=$(($(tput cols) / 2))
c=$((col-1))
est=$((c-2))
color=0
tput setaf 2; tput bold

# 打印树叶
for ((i=1; i<20; i+=2))
{
tput cup $lin $col
for ((j=1; j<=i; j++))
{
echo -n \*
}
let lin++
let col--
}

tput sgr0; tput setaf 3

# 打印树干
for ((i=1; i<=2; i++))
{
tput cup $((lin++)) $c
echo '||'
}
new_year=$(date +'%Y')
let new_year++
tput setaf 222; tput bold
tput cup $lin $((c - 10)); echo $new_year 圣 诞 节 快 乐!!!
color=122
tput setaf $color; tput bold
tput cup $((lin + 1)) $((c - 10));
let c++
k=1

#装饰一下
while true; do
for ((i=1; i<=35; i++)) {
# Turn off the lights
[ $k -gt 1 ] && {
tput setaf 2; tput bold
tput cup ${line[$[k-1]$i]} ${column[$[k-1]$i]}; echo \*
unset line[$[k-1]$i]; unset column[$[k-1]$i]
}

li=$((RANDOM % 9 + 3))
start=$((c-li+2))
co=$((RANDOM % (li-2) * 2 + 1 + start))
tput setaf $color; tput bold
tput cup $li $co
echo o
line[$k$i]=$li
column[$k$i]=$co
color=$(((color+1)%8))

sh=1
#for l in M O N E Y
for l in 圣 诞 节 快 乐
do
tput cup $((lin+1)) $((c+sh))
echo $l
let sh++
let sh++
sleep 0.02
done
}
k=$((k % 2 + 1))
done

sh test.sh

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

Yapi-Web搭建

发表于 2021-12-24
字数统计: 209 字 | 阅读时长 ≈ 1 min

test-yapi-web.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#mkdir -p /data/test-yapi-web/{db,log,config}
#项目依赖test-mongo 搭建前,启动test-mongo 若使用其他mongo,修改YAPI_DB_SERVERNAME,YAPI_DB_PORT,YAPI_DB_DATABASE
#docker-compose -f test-yapi-web.yml up -d
#test-yapi-web.yml 配置文件如下

version: '2'

services:
test-yapi-web:
image: liuqingzheng/yapi:latest
container_name: test-yapi-web
ports:
- 3000:3000
environment:
- YAPI_ADMIN_ACCOUNT=admin@qq.com
- YAPI_ADMIN_PASSWORD=admin
- YAPI_CLOSE_REGISTER=true
- YAPI_DB_SERVERNAME=test-mongo
- YAPI_DB_PORT=27017
- YAPI_DB_DATABASE=yapi
- YAPI_MAIL_ENABLE=false
- YAPI_LDAP_LOGIN_ENABLE=false
- YAPI_PLUGINS=[]
restart: always
networks:
test-net:
ipv4_address: 172.100.0.10
networks:
test-net:
external: true

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

mongoDB 数据库搭建

发表于 2021-12-23
字数统计: 235 字 | 阅读时长 ≈ 1 min

test-mongo.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#mkdir -p /data/test-mongo/{db,log,config}
#docker-compose -f test-mongo.yml up -d
#test-mongo.yml 配置文件如下

version: '2'
services:
test-mongo:
image: mongo:4.4.0 #根据需要选择自己的镜像
restart: always
ports:
- 27017:27017 #对外暴露停供服务的端口,正式生产的时候理论不用暴露。
volumes:
- /data/test-mongo/db:/data/db # 挂载数据目录
- /data/test-mongo/log:/var/log/mongodb # 挂载日志目录
- /data/test-mongo/config:/etc/mongo # 挂载配置目录
# command: --config /docker/mongodb/mongod.conf # 配置文件
container_name: test-mongo
networks:
test-net:
ipv4_address: 172.100.0.9
networks:
test-net:
external: true

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

1…151617…38

继开

一辈子很短,努力的做好两件事就好:第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。

303 日志
171 标签
RSS
gitee E-Mail
0%
鲁ICP备18007712号
© 2025 继开 | 站点字数统计: 262.2k
博客使用 Hexo 搭建
|
主题 — NexT.Mist v5.1.4
人访问 次查看