初入学习 JDBC 操作数据库,想必大家都写过下面的代码: 数据库为:H2 如果需要处理特定 SQL 异常,比如 SQL 语句错误,这个时候我们应该怎么办? 查看 SQLException 源码,我们可以发现两个重要的方法。 SQLException.getErrorCode:返回数据库特定的错误码,由数据库厂商制定,不同厂商错误码不同。如重复主键错误码在 MySQL 中是 1062,而在 Oracle 中却是 1。 SQLException.getSQLState:返回 XOPEN 或 SQL:2003 制定的错误码规范。数据库厂商会将不同错误消息映射成同一个错误码 所以我们可以根据 SQLException.getErrorCode 处理相应的数据库异常。 由于数据库厂商错误码不相同,这就导致如果我们更换数据库,上面判断逻辑就必须重写。 下面我们使用 Spring 操作数据库。 Spring 操作数据库 使用 Spring 之后,我们不再需要强制捕获异常。如果 SQL 语句运行存在异常,Spring 会抛出其内置特定的异常。如上面 SQL 语句异常将会抛出 BadSqlG.... 有更新! 从源码解析 Spring JDBC 异常抽象 数据库
Dubbo 2.7.1 踩坑记 Dubbo 2.7 版本增加新特性,新系统开始使用 Dubbo 2.7.1 尝鲜新功能。使用过程中不慎踩到这个版本的 Bug。 系统架构 Spring Boot 2.14-Release + Dubbo 2.7.1 现象 Dubbo 服务者启动成功,正常提供服务,消费者调用偶现失败的情况。错误如下图: 可以看出,主要原因为 cause: message can not send, because channel is closed。 但是检查提供者,却发现服务进程正常。 登陆 Dubbo admin 查看提供者服务,发现这个服务存在两个节点。 192.168.164.77 为测试服务器的 ip,提供者位于这台机器,而另一个 10.20.80.67 却是本地电脑的 IP,但是此时本地并未运行这个服务。 再次查看服务报错的原因,可以看到提供者调用l本地提供 RPC 的服务。由于本地服务已停止,导致调用失败。 这个问题在之前版本从未碰到,刚开始隐约记得 Dubbo 服务提供者注册使用 ZooKeeper 临时节点,服务断开,会删除该节点。 问题原因 在 D.... 有更新! Dubbo 2.7.1 踩坑记 Dubbo
支付系统一般需要对接多个支付渠道,一是为了保证系统的可靠性,不能因为单一渠道的问题影响整个支付系统。二是为了提高支付能力,不同渠道提供支付能力不同。三是为了降低支付成本。 对接多个支付渠道以后,为了可以正确选择支付渠道支付,因此设计渠道路由系统。 从上图可以看到路由系统功能其实很简单,分发支付请求到正确的渠道。但就是这个简单系统,也经过几次系统改造升级,最终才成为现在的样子。下面就来说说这个系统是如何演进。 下面假设对接支付渠道为支付宝与微信。 初期 支付系统初期,这个阶段业务需求较简单,仅仅需要满足一个支付场景(例如使用支付宝支付)。为了快速上线,设计方案就简单粗暴,对外直接暴露支付服务接口,由业务系统发起直接调用。 系统设计图如下: 这个阶段由于只有一个支付渠道,所以也不需要有路由系统,直接由业务系统调用支付服务接口发起支付。 这个设计方案存在很多问题: 业务系统与支付系统位于同一个系统,系统任何一次变更都会影响整个系统。 扩展性问题。接入新支付渠道,如微信,需要新暴露一个微信支付服务接口。业务系统需要改动代码。从另一方面讲,业务系统承担路由系统的功能。 复用性。新支付渠.... 有更新! 支付渠道路由系统进化史 支付系统
背景 现有一个交易系统,每次交易都会更新余额。出账扣减余额,入账增加余额。为了保证资金安全,余额发生扣减时,需要比较现有余额与扣减金额大小,若扣减金额大于现有余额,扣减余额不足,扣减失败。 余额表(省去其他字段)结构如下: CREATE TABLE `account` ( `id` bigint(20) NOT NULL, `balance` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_bin; 更新余额方法语序如下: 由于存在并发更新余额的情况,在 t3 时刻,使用写锁锁住该行记录。这样就能保证事务执行期间不会有其他事务提交变更。 现在我们假设有两个事务正在发执行该语序,执行顺序如图所示。 假设 id=1 记录 balance=1000,事务隔离等级为 RR。小伙伴们可以根据这个执行时序可以先思考下 t3,t5,t6,t7 结果。 注: 以上时序,顺序执行。但是事务 1 执行到 t3 时刻,t4 时刻,事务 .... 有更新! 锁住余额,为何还会更新异常? mysql
背景 相关 wiki 定义。 银企直联是指集团企业在集团内部建立自己的资金管理系统,通过数据接口将内部资金管理系统与商业银行核心系统、网银或者现金管理平台实现联接。通过银企直联系统企业可实现实时帐户信息查询、明细查询、自动转帐、交易查询等功能。并且交易的实时性和方便性得到大幅提高。“银企直联”的应用特点是连接手段不限,公网、专线均可。 下面说说一些使用银企直联的实际场景。 公司一般都会在某个银行开设对公账户,相关款项需要通过该对公账户出款。使用对公账户出款需要使用企业网银,出款流程类似我们使用个人网银出款流程。 若业务场景需要将商家的当天收款金额转账至其银行卡。未接入银企之前,财务同学需要登录企业网银,创建出款信息,然后插入银行 U 盾,确认出款。接入银企之后,可以实现自动将商家的金额汇总然后转账出款,无需繁琐的网银流程。这样可以与内部服务关联,实现线上化。 当然银企服务还可以实现查找银行流水等功能。 我司基于银企直联服务,开发了公司内部服务,很大程度解决财务打款,后期做账核对繁琐问题。 现就将本人接入几家银行经历,谈谈银企直联服务接入流程。 银企接入流程 银企接入流程: 与银行.... 有更新! 聊聊银企直联服务那些事 待分类
前言 对账系统作为支付系统中的基石系统,处于整个支付环节中的最后一层,主要用来保证我方支付数据与第三方支付渠道或银行的数据一致性。 在没有对账系统之前,财务在第二日手工核对前一日的应收与实收。倘若不一致,这就需要一一核对数据,找出不一致的数据。对账系统出现之后,就可减少以这种繁琐手工操作,财务只需要每天关注系统的对账记录,释放了生产力。 本文主要结合实际的项目经验,聊聊对账系统的设计方案。 系统整体设计 对账系统设计主要分为以下四个模块: 渠道数据处理模块 数据处理模块 核对模块 差异数据处理模块 模块调用顺序层次图如下。 下面先来介绍渠道数据处理模块。 渠道数据处理模块 这个模块主要负责渠道对账文件的下载,解析,以及数据落库。 目前市面上第三方支付渠道对账文件下载方式主要分为以下几类: 第三方渠道定时推送到 SFTP/FTP。这种模式比较简单,我们定时从 SFTP/FTP 取对账文件。 调用第三方渠道对账文件下载接口。这种模式需要对接渠道下载对账文件接口,定时调用下载。支付宝与微信为该模式。 手动在支付渠道网站下载对账文件。这种模式最不友好,需要我们花费人力下载文件。 除了.... 有更新! 从零开始设计对账系统 支付系统
2018 年余额仅剩下八九个小时,趁着这几个小时,复盘一下我的 2018 年,顺便也为即将到来的 2019 年立下几个 flag。 工作 开头先来聊聊工作吧。 四月份的时候,成功换了一份工作,开始进入支付领域。这里感谢内推的小伙伴们。 进入新公司之后,遇到了更大的挑战。以前开发,碰到数量级最多也就十万级,那时候不会过多考虑性能,随便写写的代码也能实现需求,也能满足性能。但是进入新公司之后,数量级几何级增长,碰到之前从未会碰到过的问题。这个过程中,必须强迫自己考虑更多东西。 进入公司差不多两个月之后,进入了一个新项目组的开发。在这个项目中,经历项目从立项到开发再到上线的过程。虽然这个过程十分辛苦,甚至经历一次通宵发版,但是收获最后大于付出,也真正融入团队之中。 经过这一年,熟悉了自己小组的业务,也能独挡一面。 生活 再来聊聊生活。 今年二月份,思考很久之后,终于决定去医院做了激光手术,摆脱戴了十几年的眼镜,世界变得如此清晰美丽。 十月份开始进入健身房跑步,每天大概跑个两三公里。刚开始开始跑步真的十分吃力,跑个 1 公里,几乎就累的半死。不过庆幸自己坚持了下来。虽然这两个月最后的效果也就成.... 聊聊我的 2018 年 小黑黑的碎碎念
最近经常在知乎收到类似『没基础,java 如何自学』、『怎么才能掌握编程』等等问题,再加上发现高中同学也在自学。有感而发,讲讲我的自学之路。 1.1. 大学 高考没正常发挥,考入一所二流的学校,当时分数也只高出录取分数线一两分,只能选择机械专业,当时分数如果高个两三分,或许可以上计算机专业,或许现在基础知识水平可能不一样,可是谁说的准那? 说回正题,大学前两年,跟大多数同学一样,基本在混,该打游戏打游戏,该逃课的逃课。但是期末的时候会去临时努力一把,最后也能取个好成绩。这里说一点,后来才发现有些同学原来期末的时候也不去准备一把,没办法这样也就只能挂科了。所以这里想说个观点,其实你只要稍微努力一点,其实就已经超过了很多人。 说说我们专业,跟计算机有关联可能就是『机』了吧。所幸,大一的时候还有一门 C 语言必修课。那时候其实对于编程存在懵懂的兴趣,曾想过学完 C 语言,然后成为一个黑客。可是学的时候才发现,才发现这门课是如此枯燥,而且你根本不知道学完你能干什么。书本只有练习题,老师也只是照本宣科。于是那时候也失去对这门课的兴趣。 1.2. 大三 大三那年对于我人生是有意义的一年。 那个.... 聊聊我的 Java 自学之路 小黑黑的碎碎念
这次使用分布式事务框架过程中了学习了一些分布式事务知识,所以本文我们就来聊聊分布式事务那些事。首先我们先回顾下什么是事务。 事务 什么是事务?这个作为后端开发,日常开发中只要与数据库有交互,肯定就会使用过事务。现在摘抄一段wiki的解释,解释下什么是事务。 是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成 数据库系统具有事务特性,这是其有别与文件系统重要特性。传统的文件系统,如果正在写文件,操作系统突然崩溃,此时文件可能被破坏。数据库系统引入事务特性,可以保证数据库从一种状态转换为另一种状态。在提交工作时,可以确保要么所有修改都被保存,要么所有都不保存。 通常一个事务会有多个读写操作构成。 事务具有四个基本特性,俗称ACID。 A(Atomicity):原子性。事务会被当做一个整体,要么所有语句都成功,要么都失败,不能存在部分语句成功,部分失败的情况。 C(Consistenc):一致性。数据库的状态从一种状态转变为另外一种状态,事务开始之前和是事务结束之后,数据库完整性约束不变。什么叫数据库完整性约束不变?举个例子,若一个表姓名字段为唯一约束,若在事务提.... 有更新! 聊聊分布式事务 分布式事务