【重新发现PostgreSQL之美 】- 34 月老 - 撮合系统

背景


场景:

  • 交易撮合系统

挑战:

  • 有时间优先约束, 单只股票只能串行操作, 容易导致交易拥堵的瓶颈.
  • 一笔交易涉及多份, 例如200股, 存在部分交易, 部分撤单的需求.
  • 买卖双方的数量可能不匹配, 一笔撮合交易可能涉及多方.
  • 隐蔽问题: 价格挂太高或太低, 无法撮合时, 会导致资源浪费. 类似vacuum, 有长事务, 导致垃圾不能回收, 但是依旧要触发扫描.
  • 业务层实现撮合的挑战: 与数据库需要进行很多轮交互, 并且需要在事务中完成, 事务RT和死锁问题增加. 性能弱.

PG解决方案:

  • 业务逻辑放在函数内完成, 大幅降低应用与数据库交互, 降低RT.
  • advisory lock, skip locked等技术手段避免死锁.

DEMO:


约束:

  • 时间优先
  • 价格优先
    • 买低不买高
    • 卖高不卖低
    • 限价交易, 指定价格
  • 限时交易
    • 过期未完成交易则撤单

结构设计:

1、时价表

stockid   

price  -- 时价   

ts  

2、买方pipeline

pk  

uid  

stockid  

price   

cnt  

request_ts  

deadline_ts  

modify_ts  

3、卖方pipeline

pk  

uid  

stockid  

price   

cnt  

request_ts  

deadline_ts  

modify_ts  

4、交易明细

pk  

stockid  

buyer  

provider  

cnt  

price  

status  

request_ts  

5、过期订单历史

ops  -- or  

pk  

uid  

stockid  

price   

cnt  

request_ts  

deadline_ts  

modify_ts  

请求需求:

  • 新建交易订单
  • 修改订单内容
  • 撤单

撮合函数逻辑:

参数输入stockid, batch次数(loop次数)  

逻辑:   

loop batch次数   

  删除过期订单写入过期订单历史表  

  按规则取出一条最早的待成交记录买方和卖方时间优先并且取待交易数额(cnt)小的.  

  撮合  

    更新买、卖表cnt  

    写交易明细  

    更新时价表  

end loop;  

参考


《如何用一个回形针换一栋别墅- openBarter (古人的物物交换市场类撮合交易系统》

 

 

上一篇:【重新发现PostgreSQL之美】- 36 方世玉 安全第一


下一篇:【重新发现PostgreSQL之美】- 32 天不怕地不怕, 就怕老板问为什么?