审核机制的实现以及数据库设计

概要

基于Springboot框架实现的审核机制。实现用户修改属性的审核机制和数据库访问冲突的解决

整体架构流程

整体流程图

流程解释

  1. 当一个属性被创建或修改时,会在属性表中插入或更新一条记录,并将状态设置为PENDING(待审核)。
  2. 同时,在审核表中插入一条新的审核记录,记录下申请人ID、操作类型、属性ID等信息,状态同样设置为PENDING
  3. 管理员会根据审核表中的记录进行审核,更新审核记录的状态为APPROVEDREJECTED,并记录审核人ID。
  4. 如果审核通过,属性表中的对应属性记录的状态也会更新为APPROVED;如果审核拒绝,属性表中的状态更新为REJECTED。审核表和属性表的updated_at字段会在每次记录更新时自动更新为当前时间。
  5. 前端请求得到审核通过的属性。
  6. 数据库返回所有审核通过的属性。

这个过程确保了属性的变化都经过审核流程,并且所有的审核操作都有记录可查。

流程详细介绍

数据库设计

/*
属性表 (Attributes):
id (主键)
name (属性名称)
value (属性值)
status (审核状态: 待审核、审核通过、审核拒绝)
created_at (创建时间)
updated_at (更新时间)
审核表 (AuditLogs):
*/

/*
审核表:
id (主键)
attribute_id (外键,指向属性表)
action (操作: 增加、修改、删除)
requested_by (申请人ID)
admin_reviewed (审核人ID)
status (审核结果: 待审核、通过、拒绝)
created_at (创建时间)
updated_at (更新时间)

*/

public enum Status {
    PENDING,   // 待审核
    APPROVED,  // 已通过
    REJECTED   // 已拒绝
}

数据模型解释

属性表 (Attributes)

这个表用于存储属性信息:

  • id:主键,用于唯一标识一个属性记录。
  • name:属性名称,表示属性的名称。
  • value:属性值,表示属性的值。
  • status:审核状态,用于标识属性当前所处的审核阶段,可能的值有“待审核”、“审核通过”和“审核拒绝”。
  • created_at:创建时间,记录属性记录创建的时间。
  • updated_at:更新时间,记录属性记录最后更新的时间。
审核表 (AuditLogs)

这个表用于记录属性的审核日志:

  • id:主键,用于唯一标识一条审核记录。
  • attribute_id:外键,指向属性表的主键,表示这条审核记录对应的属性。
  • action:操作,表示申请人进行的操作类型,可能的值有“增加”、“修改”和“删除”。
  • requested_by:申请人ID,表示发起审核请求的用户标识。
  • admin_reviewed:审核人ID,表示进行审核的管理员标识。
  • status:审核结果,表示审核的最终结果,可能的值有“待审核”、“通过”和“拒绝”。
  • created_at:创建时间,记录审核记录创建的时间。
  • updated_at:更新时间,记录审核记录最后更新的时间。

枚举类解释

Status 枚举

这个枚举类用于定义审核状态,包含以下三个枚举值:

  • PENDING:表示“待审核”状态,属性或审核记录正在等待审核。
  • APPROVED:表示“已通过”状态,属性或审核记录已经通过审核。
  • REJECTED:表示“已拒绝”状态,属性或审核记录未通过审核。

数据库加锁

数据库加锁从冲突角度常分为乐观锁和悲观锁

悲观锁(Pessimistic Locking)

  • 锁定资源:悲观锁在操作数据之前会锁定资源,直到事务完成才会释放锁。
  • 阻塞:如果资源被锁定,其他尝试访问该资源的操作将被阻塞,直到锁被释放。
  • 适用场景:适用于写入操作多、读取操作少,或者对数据一致性要求极高的场景。

乐观锁(Optimistic Locking)

  • 无锁操作:乐观锁在读取数据时不锁定资源,而是在更新时检查数据是否被修改过。
  • 无阻塞:不会阻塞其他事务,因此可以提供更高的并发性能。
  • 适用场景:适用于读取操作多、写入操作少。

读取大于写入操作,且每一条操作都会在审核表中记录,不会存在对资源的冲突返回,所以聚焦点在于确保自上次读取数据以来没有其他事务修改过数据。所以我们选用乐观锁来实现。

乐观锁实现步骤

使用JPA+Hibernate实现

  1. 字段添加:在属性表中添加一个version字段,该字段在每次实体被更新时递增。
  2. 注解使用:在实体类的version字段上使用@Version注解,这样Hibernate(或其他JPA实现)就知道这个字段是用来进行乐观锁控制的。
  3. 更新操作:当实体被更新时,Hibernate会自动检查version字段。在更新之前,它会读取当前实体的version值,并在更新时将其与数据库中的version值进行比较。
  4. 冲突检测:如果在读取和更新之间version值在数据库中被其他事务修改,则更新操作将失败,因为当前事务中的version值与数据库中的值不匹配。

以下是属性表实体类中version字段的示例代码:

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import java.util.Date;
@Entity
public class Attribute {
    @Id
    private Long id; // 主键
    private String name; // 属性名称
    private String value; // 属性值
    private String status; // 审核状态: 待审核、审核通过、审核拒绝
    private Date created_at; // 创建时间
    private Date updated_at; // 更新时间
    @Version
    private Integer version; // 乐观锁版本号
    // 省略构造函数、getter和setter方法
}

每次Attribute实体被更新时,version字段都会自动递增。如果两个事务尝试同时更新同一个实体,只有第一个提交的事务会成功,第二个事务会因为版本号不匹配而失败,通常会抛出一个乐观锁异常(例如OptimisticLockException)。
这种方法确保了即使在高度并发的环境中,也能保持数据的一致性,并且避免了不必要的锁定开销。

小结

分享博主在开发中遇到的问题,如果你也感兴趣,关注点赞博主,欢迎交流讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值