apache / apache/incubator-seata

postgresql 回滚事务时,接受的信息转JSON 出错

Open
#2,886 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.