apache / apache/incubator-seata
postgresql 回滚事务时,接受的信息转JSON 出错
- Dominant language
- Java
- Stars
- 26k
- Forks
- 8.8k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 4
Description
- [ ] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.
postgresql 回滚事务时,接受的信息转JSON 出错,使用的是官方的 example, 只是修改了数据库类型为 postgresql
### Ⅴ. Anything else we need to know?
收到的byte数组,转字符后可以得到一个 hex 字符串。比如
```
x7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e756e646f2e4272616e6368556e646f4c6f67222c22786964223a223139322e3136382e34372e3132383a383039313a32303136383433393735222c226272616e63684964223a323031363834333937362c2273716c556e646f4c6f6773223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e756e646f2e53514c556e646f4c6f67222c2273716c54797065223a22555044415445222c227461626c654e616d65223a226163636f756e745f74626c222c226265666f7265496d616765223a7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e5461626c655265636f726473222c227461626c654e616d65223a226163636f756e745f74626c222c22726f7773223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e526f77222c226669656c6473223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e4669656c64222c226e616d65223a226964222c226b657954797065223a225052494d4152595f4b4559222c2274797065223a342c2276616c7565223a347d2c7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e4669656c64222c226e616d65223a226d6f6e6579222c226b657954797065223a224e554c4c222c2274797065223a342c2276616c7565223a31303030307d5d5d7d5d5d7d2c226166746572496d616765223a7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e5461626c655265636f726473222c227461626c654e616d65223a226163636f756e745f74626c222c22726f7773223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e526f77222c226669656c6473223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e4669656c64222c226e616d65223a226964222c226b657954797065223a225052494d4152595f4b4559222c2274797065223a342c2276616c7565223a347d2c7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e73716c2e7374727563742e4669656c64222c226e616d65223a226d6f6e6579222c226b657954797065223a224e554c4c222c2274797065223a342c2276616c7565223a393930307d5d5d7d5d5d7d7d5d5d7d
```
而这个字符串,我使用 hex 字符串转byte数组后,在进行一次转字符串,可以得到
```
{
"@class": "io.seata.rm.datasource.undo.BranchUndoLog",
"xid": "192.168.47.128:8091:2016843975",
"branchId": 2016843976,
"sqlUndoLogs": [
"java.util.ArrayList",
[
{
"@class": "io.seata.rm.datasource.undo.SQLUndoLog",
"sqlType": "UPDATE",
"tableName": "account_tbl",
"beforeImage": {
"@class": "io.seata.rm.datasource.sql.struct.TableRecords",
"tableName": "account_tbl",
"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": "id",
"keyType": "PRIMARY_KEY",
"type": 4,
"value": 4
},
{
"@class": "io.seata.rm.datasource.sql.struct.Field",
"name": "money",
"keyType": "NULL",
"type": 4,
"value": 10000
}
]
]
}
]
]
},
"afterImage": {
"@class": "io.seata.rm.datasource.sql.struct.TableRecords",
"tableName": "account_tbl",
"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": "id",
"keyType": "PRIMARY_KEY",
"type": 4,
"value": 4
},
{
"@class": "io.seata.rm.datasource.sql.struct.Field",
"name": "money",
"keyType": "NULL",
"type": 4,
"value": 9900
}
]
]
}
]
]
}
}
]
]
}
```
这时候才能得到应该收到的数据, 使用mysql的话可以直接获取此信息,而postgresql则不行。还会抛出异常
```
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('\' (code 92)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (byte[])"\x7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e756e646f2e4272616e6368556e646f4c6f67222c22786964223a223139322e3136382e34372e3132383a383039313a32303136383437383530222c226272616e63684964223a323031363834373835312c2273716c556e646f4c6f6773223a5b226a6176612e7574696c2e41727261794c697374222c5b7b2240636c617373223a22696f2e73656174612e726d2e64617461736f757263652e756e646f2e53514c556e646f4c6f67222c2273716c54797065223a22555044415445222c227461626c654e616d65223a226163636f756e745f74626c222c"[truncated 1746 bytes]; line: 1, column: 2]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1840) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:712) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:637) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._handleUnexpectedValue(UTF8StreamJsonParser.java:2654) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._nextTokenNotInObject(UTF8StreamJsonParser.java:856) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:753) ~[jackson-core-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4340) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4189) ~[jackson-databind-2.10.2.jar:2.10.2]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3266) ~[jackson-databind-2.10.2.jar:2.10.2]
at io.seata.rm.datasource.undo.parser.JacksonUndoLogParser.decode(JacksonUndoLogParser.java:139) ~[seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.datasource.undo.AbstractUndoLogManager.undo(AbstractUndoLogManager.java:276) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.datasource.DataSourceManager.branchRollback(DataSourceManager.java:181) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.AbstractRMHandler.doBranchRollback(AbstractRMHandler.java:126) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.AbstractRMHandler$2.execute(AbstractRMHandler.java:68) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.AbstractRMHandler$2.execute(AbstractRMHandler.java:64) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.exception.AbstractExceptionHandler.exceptionHandleTemplate(AbstractExceptionHandler.java:116) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.AbstractRMHandler.handle(AbstractRMHandler.java:64) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.DefaultRMHandler.handle(DefaultRMHandler.java:63) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.protocol.transaction.BranchRollbackRequest.handle(BranchRollbackRequest.java:35) [seata-all-1.2.0.jar:1.2.0]
at io.seata.rm.AbstractRMHandler.onRequest(AbstractRMHandler.java:151) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.rpc.netty.RmMessageListener.handleBranchRollback(RmMessageListener.java:93) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.rpc.netty.RmMessageListener.onMessage(RmMessageListener.java:84) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.rpc.netty.AbstractRpcRemotingClient$ClientHandler.dispatch(AbstractRpcRemotingClient.java:284) [seata-all-1.2.0.jar:1.2.0]
at io.seata.core.rpc.netty.AbstractRpcRemoting$AbstractHandler$1.run(AbstractRpcRemoting.java:452) [seata-all-1.2.0.jar:1.2.0]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.45.Final.jar:4.1.45.Final]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
```
Contributor guide
Research direction
Start with JacksonUndoLogParser.java at decode(), then trace the rollback path through AbstractUndoLogManager.undo and DataSourceManager.branchRollback. Reproduce the official example with PostgreSQL and inspect existing undo-log parser tests or add a focused regression case. Done means PostgreSQL rollback data is accepted as JSON without the reported JsonParseException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, postgresql
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100