This commit is contained in:
zhangzhiqiang
2023-04-27 15:20:46 +08:00
commit be0566e379
96 changed files with 2309 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package nl.org.transactionaldemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartApplication {
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
}

View File

@@ -0,0 +1,79 @@
package nl.org.transactionaldemo.server.JDK新特性.stream流;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/*
* @author ZZQ
* @Date 2023/4/27 13:46
*/
public class StreamDemo {
public static void main(String[] args) {
List<DataEntity> list = extracted(100);
//1.字段汇总
Set<String> collect = list.stream()
.map(DataEntity::getName).collect(Collectors.toSet());
//2.条件过滤
List<DataEntity> collect1 = list.stream().filter(dataEntity -> dataEntity.getClassNo().equals("NO.3")).collect(Collectors.toList());
//3.分组
Map<String, List<DataEntity>> map = list.stream().collect(Collectors.groupingBy(dataEntity -> dataEntity.getClassNo()));
//4.转换
Map<String, DataEntity> map2 = list.stream().collect(HashMap::new, (k, v) -> k.put(v.getName(), v), HashMap::putAll);
}
private static List extracted(int count) {
List<DataEntity> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
DataEntity entity = new DataEntity();
entity.setName(UUID.randomUUID().toString());
entity.setAge(new Random().nextInt(20)+1);
entity.setClassNo("NO."+(i%3+1));
list.add(entity);
}
return list;
}
}
class DataEntity{
private String name;
private Integer age;
private String classNo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
@Override
public String toString() {
return "DataEntity{" +
"name='" + name + '\'' +
", age=" + age +
", classNo='" + classNo + '\'' +
'}';
}
}

View File

@@ -0,0 +1,56 @@
package nl.org.transactionaldemo.server.JDK新特性.函数式接口;
import java.util.function.Function;
/*
* @author ZZQ
* @Date 2023/4/27 14:28
*/
public class FuntureDemo {
public static void main(String[] args) {
//1.接口继承:重写方法
NumProcess numProcess = new NumProcess();
numProcess.process(3);
//2.正常业务处理:文字处理业务中需要引入数字处理业务
StringProcess process = new StringProcess();
process.process();
//3.以参数的形式带入
process.process(new NumProcess());
//4.匿名内部类
process.process(new Process() {
@Override
public Object process(Object o) {
return (Integer)o*2;
}
});
//5.函数式接口
process.process((a)-> ((Integer) a)*2);
}
}
@FunctionalInterface
interface Process<T,R>{
R process(T t);
}
class NumProcess implements Process<Integer,Integer>{
@Override
public Integer process(Integer integer) {
return integer*2;
}
}
class StringProcess implements Process<Process,String>{
@Override
public String process(Process process) {
return "NO."+process.process(3);
}
public String process() {
//使用到数据处理业务:
NumProcess numProcess = new NumProcess();
return "NO."+numProcess.process(3);
}
}

View File

@@ -0,0 +1,84 @@
package nl.org.transactionaldemo.server.事务.事务注解;
import org.springframework.stereotype.Service;
@Service
public class GenCodeServiceImpl {
// @Override
// @Transactional(propagation = Propagation.REQUIRES_NEW)
// public String codeDemo(Map form) {
// String code = (String) form.get("code");
// String id = this.queryIdByCode(code);
// //如果flag=1就执行更新数据库的操作
// String flag = (String) form.get("flag");
// WQLObject wo = WQLObject.getWQLObject("sys_code_rule_detail");
// JSONArray ja = wo.query("code_rule_id = '" + id + "' order by sort_num FOR UPDATE").getResultJSONArray(0);
// String demo = "";
// boolean is_same = true;
// for (int i = 0; i < ja.size(); i++) {
// String value = "";
// JSONObject jo = ja.getJSONObject(i);
// //固定直接取值
// if (jo.getString("type").equals("01")) {
// value = jo.getString("init_value");
// }
// //日期判断数据库的值与当前值是否相同来决定顺序的值
// if (jo.getString("type").equals("02")) {
// String current_value = jo.getString("current_value");
// Date date = DateUtil.date();
// String format = jo.getString("format");
// String now_date = DateUtil.format(date, format);
// if (!now_date.equals(current_value)) {
// is_same = false;
// }
// if (flag.equals("1")) {
// jo.put("init_value", now_date);
// jo.put("current_value", now_date);
// }
// value = now_date;
// }
// //顺序的值:如果日期一样就+步长,等于最大值就归为初始值;日期不一样就归为初始值
// if (jo.getString("type").equals("03")) {
// String num_value = "";
// int step = jo.getInteger("step");
// Long max_value = jo.getLong("max_value");
// if (!is_same || (jo.getLongValue("current_value") + step > max_value)) {
// num_value = jo.getString("init_value");
// } else {
// num_value = (jo.getInteger("current_value") + step) + "";
// }
// int size = num_value.length();
// int length = jo.getInteger("length");
// String fillchar = jo.getString("fillchar");
// for (int m = 0; m < (length - size); m++) {
// value += fillchar;
// }
// value += num_value;
// if (flag.equals("1")) {
// if (!is_same) {
// int init_value = jo.getInteger("init_value");
// if (StrUtil.isEmpty((init_value + ""))) {
// throw new BadRequestException("请完善编码数值的初始值!");
// }
// jo.put("current_value", init_value + "");
// } else {
// int num_curr = jo.getInteger("current_value");
// if (num_curr >= max_value) {
// num_curr = jo.getInteger("init_value");
// jo.put("current_value", num_curr + "");
// }else{
// jo.put("current_value", (num_curr + step) + "");
// }
// }
// }
// }
// demo += value;
// if (flag.equals("1")) {
// wo.update(jo);
// }
// }
// return demo;
// }
}

View File

@@ -0,0 +1,132 @@
package nl.org.transactionaldemo.server.事务.编程事务;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/*
* 分段回回滚:
* 注意事项:
* 1.思考资源释放问题spring是怎么释放资源
* 2.为什么外层需要加@Transactional 手写编程事务不会报错,原理是什么
* 3.封装手写编程事务,只让用户关注自身业务代码。可以参考.jdk8特性Function等函数表达式的使用
* 4.jdk8特性stream流管道处理替换for循环的学习
*/
public class TransationDemo {
//分批回滚每个for循环都会占用链接
@Autowired
private PlatformTransactionManager txManager;
// @Transactional
public void creteTask(JSONArray request){
List<TransactionStatus> statusCollent = new ArrayList<>();
try {
HashMap<String, TransactionStatus> map = new HashMap<>();
for (int i = 0; i < request.size(); i++) {
//生成新事务
JSONObject param = request.getJSONObject(i);
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = txManager.getTransaction(def);
String taskId = IdUtil.randomUUID();
//业务代码,生成任务
//bussTab.insert(param)
//taskTab.insert(taskId);
map.put(taskId,status);
statusCollent.add(status);
}
//acs反馈异常taskid
List<String> errorTaskIds = new ArrayList<>();
errorTaskIds.add("1232");
errorTaskIds.add("3224");
List<TransactionStatus> errCollect = map.entrySet().stream()
.filter(tmap -> errorTaskIds.contains(tmap.getKey()))
.map(tmap -> tmap.getValue())
.collect(Collectors.toList());
//异常的资源回滚
for (TransactionStatus status : errCollect) {
statusCollent.remove(status);
txManager.rollback(status);
}
}finally {
//剩余资源资全部提交
if (!CollectionUtils.isEmpty(statusCollent)){
for (TransactionStatus value : statusCollent) {
txManager.commit(value);
}
}
}
}
}
//封装参考
class TransactionManagerUtil{
public static void main(String[] args) {
//demo
JSONArray request = new JSONArray();
TransactionManagerUtil.openTransaction((req, allTransactionConsumer) -> {
for (Object param : req) {
String taskId = UUID.randomUUID().toString();
allTransactionConsumer.accept(taskId);
//业务代码,生成任务
//bussTab.insert(param)
//taskTab.insert(taskId);
}
//acs反馈异常taskid
ArrayList errorTask = new ArrayList();
return errorTask;
},request);
}
static Object openTransaction(BiFunction<JSONArray, Consumer<String>,List> function, JSONArray request){
PlatformTransactionManager txManager = null; //SpringContextHolder.getBean(PlatformTransactionManager.class);
Map<String, TransactionStatus> statusMap = new HashMap<>();
List<TransactionStatus> errTask;
try {
//创建所有事务集合
Consumer<String> allTransactionConsumer = task -> {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = txManager.getTransaction(def);
statusMap.put(task,status);
};
//业务
errTask = function.apply(request,allTransactionConsumer);
//过滤异常事务的任务id
List<TransactionStatus> collect = statusMap.entrySet().stream()
.filter(tmap -> errTask.contains(tmap.getKey()))
.map(tmap -> tmap.getValue())
.collect(Collectors.toList());
for (TransactionStatus status : collect) {
statusMap.remove(status);
txManager.rollback(status);
}
}finally {
//释放剩余资源
if (!CollectionUtils.isEmpty(statusMap)){
for (TransactionStatus value : statusMap.values()) {
txManager.commit(value);
}
}
}
return null;
}
}
//封装参考

View File

@@ -0,0 +1,31 @@
package nl.org.transactionaldemo.server.锁;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/*
* @author ZZQ
* @Date 2023/4/19 12:55
*/
@RestController
@RequestMapping("/sync")
public class SyncController {
@RequestMapping("/block")
public String syncBlock(@RequestBody JSONObject param) throws InterruptedException {
/**
* 数据处理过程:
* 通过类型解析器解析输入流根据targetType生成参数对象newInstance;
* String str = currLen == 0 ? "" : new String(this._currentSegment, 0, currLen);
*/
synchronized (param.getString("type")){
System.out.println(System.identityHashCode(param.getString("type")));
System.out.println(System.identityHashCode(param.getString("type").intern()));
Thread.sleep(5000);
System.out.println("----------"+Thread.currentThread().getName()+"----------");
return param.getString("type")+" sucess!!!";
}
}
}

View File

@@ -0,0 +1,47 @@
spring:
datasource:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
#url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:hl_one_mes}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
url: jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:hl_one_mes}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
username: ${DB_USER:root}
#password: ${DB_PWD:P@ssw0rd}
#password: ${DB_PWD:root}
password: ${DB_PWD:Root.123456}
# 初始连接数
initial-size: 5
# 最小连接数
min-idle: 15
# 最大连接数
max-active: 30
# 是否自动回收超时连接
remove-abandoned: true
# 超时时间(以秒数为单位)
remove-abandoned-timeout: 180
# 获取连接超时时间
max-wait: 3000
# 连接有效性检测时间
time-between-eviction-runs-millis: 60000
# 连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
# 连接在池中最大生存的时间
max-evictable-idle-time-millis: 900000
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
test-while-idle: true
# 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
test-on-borrow: true
# 是否在归还到池中前进行检验
test-on-return: false
# 检测连接是否有效
validation-query: select 1
# 配置监控统计
webStatFilter:
enabled: true
stat-view-servlet:
enabled: true
url-pattern: /druid/*
reset-enable: false
filters:
DruidFilter,stat

View File

@@ -0,0 +1,13 @@
package nl.org.transactionaldemo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TransactionalDemoApplicationTests {
@Test
void contextLoads() {
}
}