![]() |
1
wd 171 天前 via iPhone
数据库 trigger
|
![]() |
2
totoro52 171 天前 via iPhone ![]() 我的做法是 binlog ,用 canal 解析 binlog 在写入日志数据库,同步到 es , 完全和业务层解偶,缺点是无法记录用户的 ip 等,不过业务日志只要记录业务行为就行了,剩下的交给系统日志
|
![]() |
3
taloricag OP @totoro52 谢谢大佬,但是场景不太符合我,因为我的场景不是完全跟业务解耦,还有条件触发,比如修改了 A 字段需要发个邮件,修改了 B 字段发个通知这种,给我整蒙了
|
![]() |
4
rrfeng 171 天前 via Android
gorm 有 hooks 啊
|
5
cs419 171 天前
client 驱动层
修改 github.com/go-sql-driver/mysql 进行 aop |
![]() |
6
fgwmlhdkkkw 171 天前 via Android
只记请求和 sql ,然后再用 sql 解析器,取出来字段。
|
9
Fule 169 天前
SQL Server 2016+ 有 Temporal Table ,自动维护整行历史记录,一定程度上有助于这类问题,不知道其它数据库是否有类似特性:
https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2016 |
![]() |
10
shigella 169 天前
canal
|
11
cnit 169 天前
``` java
@Component @CanalTable("table_name") public class OrderHeaderHandler implements EntryHandler { @Autowired private XxxService xxxService; @Override public void update(Map<String, String> before, Map<String, String> after, Set<String> updateColumns) { //获取需要记录日志的列 Map<String, String> filedMap = FieldUtils.objectToMap(TableName.class, updateColumns); String tableId= before.get("tableId"); String records = ""; if (filedMap != null && filedMap.keySet().size() > 0) { for (String update : filedMap.keySet()) { String comment = filedMap.get(update); String beforeValue = before.get(update); String afterValue = after.get(update); records = records.concat(String.format("%s 由 %s 改为 %s", comment, StringUtils.isEmpty(beforeValue) ? "空" : beforeValue , StringUtils.isEmpty(afterValue) ? "空" : afterValue) + ";"); } //记录日志 OperationRecords operationRecords = new OperationRecords(); operationRecords.setLinkedId(Long.parseLong(orderId)); operationRecords.setRecords(records); operationRecords.setTableName("container_transport_order_header"); operationRecords.setCreateTime(new Date()); operationRecords.setCreateUserId(parseLongUserId(after.get("updateUserId"))); operationRecordsService.save(operationRecords); } } ``` |
12
onhao 169 天前
|