问题描述

字段 order_service_type,MySQL 数据类型为 tinyint,存储值为4,导致在 Seata 回滚时,无法回滚到正确的状态。变成1了。

问题排查

通过 Debug,查看 Seata undo_log 表,发现 order_service_type 在生成快照时被当作 Boolean 值处理了,回滚的时候转成1写入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
{
"@class": "io.seata.rm.datasource.undo.BranchUndoLog",
"branchId": 2090276239587073061,
"sqlUndoLogs": [
"java.util.ArrayList",
[
{
"@class": "io.seata.rm.datasource.undo.SQLUndoLog",
"sqlType": "UPDATE",
"tableName": "xxxxx",
"beforeImage": {
"@class": "io.seata.rm.datasource.sql.struct.TableRecords",
"tableName": "xxxx",
"rows": [
"java.util.ArrayList",
[
{
"@class": "io.seata.rm.datasource.sql.struct.Row",
"fields": [
"java.util.ArrayList",
[


{
"@class": "io.seata.rm.datasource.sql.struct.Field",
"name": "order_service_type",
"keyType": "NULL",
"type": -7,
"value": true
}
]
]
}
]
]
},
"afterImage": {
"@class": "io.seata.rm.datasource.sql.struct.TableRecords",
"tableName": "xxx",
"rows": [
"java.util.ArrayList",
[
{
"@class": "io.seata.rm.datasource.sql.struct.Row",
"fields": [
"java.util.ArrayList",
[
{
"@class": "io.seata.rm.datasource.sql.struct.Field",
"name": "order_service_type",
"keyType": "NULL",
"type": -7,
"value": true
}
]
]
}
]
]
}
}
]
]
}

解决方案

  1. 使用 MySQL INT 类型
  2. 如果不需要,更新的时候不更新该字段。(比如不使用 MyBatis Plus 的 updateById 模板方法)