Service手动回滚事务

很多业务场景下,可以使用自动回滚事务。
如在一个Service中,可以使用注解形式整体回滚事务。

1
2
3
4
5
6
7
8
9
10
@Transactional(rollbackFor = Exception.class)
public Boolean methodName() {
boolean flag = true;
if (flag) {
// 处理业务
} else {
throw new RuntimeException("xxx");
}
return flag;
}

但也可能遇到如果对外提供API方法(RPC)需要捕获异常的处理业务的话,对于接口调用方仅需要知道错误信息即可,无需了解堆栈信息,此时try-catch后可以手动回滚事务。

1
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

1
2
3
4
5
6
7
8
9
10
11
@Transactional
public Boolean methodName() {
boolean flag = true;
try {
// 处理业务
} catch(Exception e) {
// log
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return flag;
}
Comments

线程池中Feture使用

最近遇到一个业务场景:
在导出Excel的时候、Service查询数据库数据返回List集合,数据量很大,在请求完数据以后还需要遍历调用其他中心RPC服务,这种业务场景下无法完成,超时等在所难免。
考虑到多线程处理业务。
顺便提一下……真的很难受,大数据量分片查询ES本来就很慢,真心很无奈。

Futrue:对于多线程来说,可以先拿到一个未来的Future,等所有分支取到结果后在组合数据。阻塞线程。

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
Vector<Map<String,Object>> dataList = new Vector<>();
// 按照业务场景自定义分页大小
int pageSize = 1000;
// 按照CPU核心数自定义线程大小
int processor = 1 << 3;
ExecutorService executorService = new ThreadPoolExecutor(processor, processor, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque(),
new ThreadFactoryBuilder().setNameFormat("package-task-%d").build());
try {
// 选择分页方式查询
int totalPage = (total % pageSize == 0) ? (total / pageSize) : (total / pageSize) + 1;
List<Future<List<Map<String, Object>>>> futures = new ArrayList<>();
for (int i = 1; i <= totalPage; i++) {
final int page = i;
Future<List<Map<String, Object>>> task = executorService.submit(() -> {
PageResult<Map<String, Object>> result = XXX;
List<Map<String, Object>> listData = result.getListData();
return listData;
});
futures.add(task);
}
for (Future<List<Map<String, Object>>> future : futures) {
dataList.addAll(future.get());
}
executorService.shutdown();
} catch (Exception e) {
executorService.shutdown();
return Collections.emptyList();
}

future.get方法:获取计算结果(如果还没计算完,也是必须等待的)

future.cancel方法:还没计算完,可以取消计算过程

future.isDone方法:判断是否计算完

future.isCancelled方法:判断计算是否被取消

Comments

真真正正第一次的GitHub开源之旅

Emmm,坚持GitHub的旅行也快到一年了,通过这个‘同性交友’的网站真的学到了很多知识,不仅仅是技术上的积累,还有那许许多多开拓眼界的项目。

划重点

RSSHub是我参与的一个开源项目,介绍请看项目链接哦~虽然仅仅提交了一个分支,但这份参与感,这份点滴积累让我收益很多。

从中学习到了什么?

每一位对代码质量有着‘洁癖’的开发者们让你体会到了哪怕一个小事也要做到最好。开发思想在慢慢的积累到未来的成熟。对待每一个项目的了解程度都会影响到项目的发展和未来的规划。

上面这些可能目前自己用的少(其实有些用不到)但是我相信未来的开源路上会用到他们的。

虽然参与的路上遇到了一些小坎坷,但看到了最后的结果!相信自己可以做好。
image

未来的路,继续加油!(勿忘初心:走的久了,不要忘记自己为什么出发)

Comments

什么是@PostConstruct,@PreDestroy注解

首先这两个注解是在JDK1.5增加的,注解@PostConstruct允许在Bean初始化之前执行一些方法,而@PreDestroy是在Bean销毁之前执行的操作。

@PostConstruct(@PreDestroy):被@PostConstruct修饰的方法会在服务器加载Servlet(Bean)的时候运行,并且只会被服务器调用一次。

生命周期如下:

1
2
3
4
5
graph LR
PostConstruct-->init
init-->some-methods
some-methods-->destory
destory-->PreDestroy

例如如下代码:

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
/**
* <p>Title: RegistryCenterConfig. </p>
* <p>Description 调度作业,Zookeeper配置(ZK集群配置) </p>
*
* @author dragon
* @date 2018/5/7 上午11:08
*/
@Configuration
@ConditionalOnClass(ElasticJob.class)
@ConditionalOnBean(annotation = MarkElasticJob.class)
@EnableConfigurationProperties(ZookeeperRegistryProperties.class)
@ConditionalOnExpression("'${elaticjob.zookeeper.server-lists}'.length() > 0")
public class RegistryCenterConfig {
private final ZookeeperRegistryProperties regCenterProperties;
@Autowired
public RegistryCenterConfig(ZookeeperRegistryProperties regCenterProperties) {
this.regCenterProperties = regCenterProperties;
}
/**
* <p>Title: regCenter. </p>
* <p>初始化配置中心 </p>
*
* @param serverList 服务列表
* @param namespace 名称
* 注意,在console上配置注册中心时,需要注意:
* 注册中心名称和命名空间->需要和namespace保持一致
*/
@Bean(initMethod = "init")
public ZookeeperRegistryCenter regCenter(@Value("${elaticjob.zookeeper.server-lists}") final String serverList,
@Value("${elaticjob.zookeeper.namespace}") final String namespace) {
ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration(serverList, namespace);
zookeeperConfiguration.setBaseSleepTimeMilliseconds(regCenterProperties.getBaseSleepTimeMilliseconds());
zookeeperConfiguration.setConnectionTimeoutMilliseconds(regCenterProperties.getConnectionTimeoutMilliseconds());
zookeeperConfiguration.setMaxSleepTimeMilliseconds(regCenterProperties.getMaxSleepTimeMilliseconds());
zookeeperConfiguration.setSessionTimeoutMilliseconds(regCenterProperties.getSessionTimeoutMilliseconds());
zookeeperConfiguration.setMaxRetries(regCenterProperties.getMaxRetries());
zookeeperConfiguration.setDigest(regCenterProperties.getDigest());
return new ZookeeperRegistryCenter(zookeeperConfiguration);
}
/**
* <p>Title: ElasticJobConfig. </p>
* <p>在初始化Zookeeper前,注入Elastic-Job,自动扫描开放任务 </p>
*
* @author dragon
* @date 2018/5/9 下午2:35
*/
@PostConstruct
public ElasticJobConfig initElasticJob() {
return new ElasticJobConfig();
}
@PreDestroy
public void preDestoryMethod() {
System.out.println("preDestoryMethod...");
}
}

对于如上代码,应用场景是elastic-job + zk 的启动方式,需要在zk启动前,先扫描Jobs,然后在执行Zk的init方法。

运行如下:

1
2
3
4
5
graph LR
RegistryCenterConfig-->ElasticJobConfig
ElasticJobConfig-->Autowired-RegistryCenterConfig
Autowired-RegistryCenterConfig-->init(regCenter)
init(regCenter)-->preDestoryMethod
Comments

Druid连接池配置连接属性utf8mb4

由于在配置了MySQL数据库,表的编码类型为utf8mb4以后需要重新启动数据库,可由于线上场景的等一些问题的影响,可用过druid设置编码方式。从而让emoji表情可以保存。😈

1
2
3
4
// 配置druid支持表情
String connectionInitSqls = "SET NAMES utf8mb4";
StringTokenizer tokenizer = new StringTokenizer(connectionInitSqls, ";");
druidDataSource.setConnectionInitSqls(Collections.list(tokenizer));

Comments

聊聊我的域名史

最近很想收集几个有意义的域名哎…

谈一谈我的域名史吧…

在大学时期,我申请的第一个域名是idragonyuan.com,因为名字很长所以我就换了目前主站使用的dragon-yuan.me域名,但是真的很喜欢dragon.me这个域名,但是可爱的他貌似在一位米农的手中,而且我也不知道从他人手中购买域名的流程是什么,但这个域名肯定好贵好贵的哎。于是在去年的时候moe域名出现了,还是老样子喽,想入手一个dragon.moe发现已经有人提前注册了,无奈之下只好注册了一个loong.moe,我也叫他萌龙。

最近也在想一些好一点的域名,有收藏意义,可能未来还会有商业价值的说呢!

Comments

Spring Boot加载yaml配置到Bean

Spring Boot可能遇到项目启动无法加载yaml配置的情况,可以使用如下配置注入PropertySourcesPlaceholderConfigurer

1
2
3
4
5
6
7
8
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("xxx.yml"));
configurer.setProperties(yaml.getObject());
return configurer;
}

Comments

时间轴,一年前的自己(2017-2018)

发现已经好久没有写过关于自己生活上的博客文章了,今天还是5月4日青年节。前几日就想写一写自己在一年中有发生了什么变化。

去年的这个时候,准备毕业的我已经从北京返回了哈尔滨。回忆下在毕业前到现在自己都做了些什么吧。17年4月份,我从实习单位提出了离职,当时公司还有很多的变化,实习单位是一个复式办公的环境,在我走之后之前的小伙伴们搬到了楼上,楼梯上看到一句话让我深深的记在了心里,勿忘初心。

image

还有那最后一次的地铁,坐上地铁心情并没有很复杂,相反变得平静了很多。

image

4月末给自己留出了几天的假期,其他的日子早上都在写毕业论文,而晚上则是学习新的知识,也逐渐的在GitHub上坚持了一个礼拜的push记录,两个项目:第一个是把实习单位所收获的做了积累,并完成了AprilDragonSpring虽然是个初学者项目,懵懂时期的自己也是需要有从0到1的过程吧。第二个项目是个成型的web项目Ins_fb_pictureSpider_WEB具体内容要是感兴趣就去看Readme吧。

刚才有提到几天自己的小假期,去了北京天安门城楼、故宫博物院、牛街、中关村、西北旺……
还记得自己发过的一条微博,说自己有朝一日一定要去中关村上班,感受互联网工作文化,梦想也在毕业后实现了。

image

还有一件对于我来说很重要的事情,去了G.E.M.的演唱会,第二次的演唱会,有一些找不到第一次看演唱会的感觉,但气氛棒的没说儿!

image

四月的最后一天,坐上了回家的火车。

image

五月返校到六月份,偶尔也会出去喝点,但绝大部分的时间都是在寝室修改论文格式,要不就是守望先锋,当时吃鸡还玩的比较少。最后的大学时光可能也没有很珍惜,心里一直想着赶快毕业,到时候能找个好一点的工作,大学最后的生活过得很快,两个月就这么过去了,四年的日子也画上了句号。失去后才懂得珍惜过去,可是那还会怎样呢…

image

毕业后在家混了几天的日子就发现自己有些待不住了,整理了下面试的知识然后看了下一位朋友送的面试宝典,带着那所谓的梦后重新踏上了北京的路。7月份炎热的北京,只要出去就会汗流浃背。找工作的路上还是顺利的,1号收到offer,3号入职,有运气有贵人,可能在找工作上这小‘命’还是不错的说。工作上也学到的很多知识,开阔了眼界,掌握了许多较为流行的开发思想,一直都在努力学习,并坚持向GitHub上push积累的知识,也算是自己成长道路上的点滴记录。

我很喜欢在之前的时间轴上走上那么一走,于是8月份去了趟朝阳公园,每次去的感觉都会有不一样的收获,不知道有没有朋友和我有一样的感觉。十月份假期回了趟家,工作上转正了,给老爹买了部手机,给老妈买了些北京特产,其实北京的特产也没太多值得带回去的,每年都会买一大盒稻香村,虽然妈妈总说太沉了就别往家里带了,但也算自己的心意吧。貌似是十月份回来去的恭王府,可能具体的时间想不起来了,不知道为什么记忆力会变得很差哎。

image

十一月份除了双十一剁手之外,还听了JD和阿里云溪大会的讲座,这也是我第一次参加这样的大会,JD基础架构还是干货挺多的,可因为自己水平有限,听懂的很少,作为开拓眼界还是足够的。

image

十二月末还代表技术部门去总部参加了年会表演,第一次去河南,长葛市,参观了总部的工厂和流水线,也让我在业务上进一步的了解了生鲜行业和供应链体系。有句话叫做见多识广,也很荣幸在毕业后就可以有机会更多的了解社会‘生态’。

image

先说过年吧,18年到来了,这也是二月份的事情了,回到家,年味依旧没有小时候那么浓郁,初一亲戚来到家里,也就聊一聊一年各家都怎么样,有要考学的,有要复习的,上班的,生子的,各家过着各家的小日子。‘年’对于我来说除了回家看看,就是见见同学朋友,吃吃饭、聊聊天、冰天雪地浪一浪也就算过完了。

image

回到了工作上,一月份的公司组织调整,两个业态的整合,也预示着单位3月份要有紧张的工作任务了,年前梳理好工作计划,而自己也帮助领到完成我力所能及的工作,构建项目,制定自己的工作计划,能做的或者预支的工作我都会主动承担,不管做多做少,反正收获的都是自己的,不论未来怎样,做好自己的工作就是最好的回报。经历了‘331’的上线,一个月都在加班中付出着,加班100个小时的自己,学会的很多也成长了很多。感受到了‘互联网’模式的开发周期,也深深的体会到了程序猿这个行业的效率。附上一张早晨5点钟的中关村吧。

image

四月份总是想写一下一年的总结,心里可能是想了很多的事情让自己失眠并稍微有些抑郁。再加上偷懒直到今日才了却心中的这件事情,希望自己在今后的路,继续加油,不忘初心。

image

Comments