《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7035630158706901028 「菜菜bu菜」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

前言

今天给大家带来也是比较实用的功能,用Java来生成序列号/订单号,列举几个在我们生活中比较常见的案例:

  • 订单号
  • 商品编号
  • 交易单号
  • 快递单号

数据存储我是使用的 mysql,下面就向大家分享一下是如何实现的~

理论知识

什么是事务?

数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

脏读、不可重复读、幻读

1、脏读:A 事务对数据修改但还没有提交到数据库,这个时候 B 事务来访问,那么 B 事务对数据就不是最新的,这种现象被成为脏读。

2、不可重复读:A 事务多次读取一个数据,这个时候在中途 B 事务修改了数据,导致 A 事务多次读到的结果不一致。

3、幻读:A 事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行,因为 B 事务在后一次查询前新增加了一条数据。

mysql 的四种隔离级别

按照隔离的级别由低到高,越高的隔离,效率越差不可重复读,是 MySQL 的默认隔离级别

1、读未提交:允许别的事务,去读取这个事务为提交之前的数据 缺点:可能会造成脏读、幻读、不可重复读。

2、不可重复读:并发条件下会出现问题,比如:A 用户读取数据, 随后 B 用户读出该数据并修改, 此时 A 用户再读取数据时发现前后两次的值不一致 缺点:可能会造成幻读、不可重复读。

3、可重复读:当使用可重复读隔离级别时,在事务执行期间会锁定该事务以任何方式引用的所有行。缺点:幻读

4、串行化:不会使用 mysql 的 mvcc 机制,在每一个 select 请求下获得读锁,在每一个 update 操作下尝试获得写锁。缺点:效率最差

两种悲观锁

共享锁 (S 锁): 如果事务 T 对数据 A 加上共享锁后,则其他事务只能对 A 再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

排它锁 (X 锁):如果事务 T 对数据 A 加上排他锁后,则其他事务不能再对 A 加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

Java 代码实现

private  String createNewBidNumber() {
//格式说明 CODE20201111xxx CODE+当前年月日+编号(具体长度看需求)
String front="CODE";//前缀
//当前时间编码
Date date = new Date();
String bidDate = new SimpleDateFormat("yyyyMMdd").format(date);
Object bidService=null;//修改为自己的业务代码
if (bidService != null){// 在数据表中查到了,说明现在这个订单不是今天的第一单
String bid = bidService.getXXXX(); //取出ID,也就是业务号
bid = bid.substring(10,13); // 取出后三位数,也就是自动生成的三位数 001
int num = Integer.valueOf(bid);
num ++; // 加1
if(num<10){
String bidNum = String.format("%03d", num);//%03d 只是三位,不足补0
String code = front+bidDate+bidNum;
return code;
}
else if(num<100){
String bidNum = String.format("%03d", num);//num<100,说明是两位数,前面要补一个0
String code = front+bidDate+bidNum;
return code;
}
else {
String bidNum = String.valueOf(num);
String code =front+bidDate+bidNum;
return code;
}
}else {
int number = 1;
String bidNum = "00" + number;
String code = front+bidDate+bidNum;
return code;
}
}
文章目录
  1. 1. 前言
  2. 2. 理论知识
    1. 2.1. 什么是事务?
    2. 2.2. 脏读、不可重复读、幻读
    3. 2.3. mysql 的四种隔离级别
    4. 2.4. 两种悲观锁
  3. 3. Java 代码实现