8.15.2.3.2. 从每个 XID 中提取全局事务 ID 和节点标识符
识别所有用于 in-doubt 分支的 XID 时,将 XID 转换为您可以与事务管理器的交易表中存储的日志进行比较的格式。
例如,以下 Bash 脚本可用于执行这一转换:假设 $PG_XID
从上述 选择语句 中保存 XID,则 JBoss EAP 事务 ID 可以按如下方式获取:
PG_XID="$1" IFS='_' read -ra lines <<< "$PG_XID" [[ "${lines[0]}" = 131077 ]] || exit 0; # this script only works for our own FORMAT ID PG_TID=${lines[1]} a=($(echo "$PG_TID"| base64 -d | xxd -ps |tr -d '\n' | while read -N16 i ; do echo 0x$i ; done)) b=($(echo "$PG_TID"| base64 -d | xxd -ps |tr -d '\n' | while read -N8 i ; do echo 0x$i ; done)) c=("${b[@]:4}") # put the last 3 32-bit hexadecimal numbers into array c # the negative elements of c need special handling since printf below only works with positive # hexadecimal numbers for i in "${!c[@]}"; do arg=${c[$i]} # inspect the MSB to see if arg is negative - if so convert it from a 2’s complement number [[ $(($arg>>31)) = 1 ]] && x=$(echo "obase=16; $(($arg - 0x100000000 ))" | bc) || x=$arg if [[ ${x:0:1} = \- ]] ; then # see if the first character is a minus sign neg[$i]="-"; c[$i]=0x${x:1} # strip the minus sign and make it hex for use with printf below else neg[$i]="" c[$i]=$x fi done EAP_TID=$(printf %x:%x:${neg[0]}%x:${neg[1]}%x:${neg[2]}%x ${a[0]} ${a[1]} ${c[0]} ${c[1]} ${c[2]})
完成后,$EAP_TID
变量保存创建此 XID 的交易的全局事务 ID。启动事务的 pod 的节点标识符由以下 bash 命令的输出提供:
echo "$PG_TID"| base64 -d | tail -c +29
注意
节点标识符从 PostgreSQL 全局事务 ID 字段的 29 字符开始。
- 如果此 pod 仍在运行,则仅保留此 in-doubt 分支,因为事务仍在运行。
如果此 pod 未在运行,您需要为事务日志搜索相关的事务日志存储。日志存储位于 JDBC 表中,它命名如下
os<node-identifier>jbosststxtable
模式。- 如果没有这样的表,将分支单独保留为归某些其他事务管理器所有。包含此表的数据源的 URL 在下方显示的 transaction 子系统描述中定义。
如果有这样的表,请查找与全局事务 ID 匹配的条目。
- 如果表中有一个与全局事务 ID 匹配的条目,则需要使用数据源供应商工具提交 in-doubt 分支,如下所述。
- 如果没有这样的条目,则分支是孤立的,可以安全地回滚。
以下是如何提交 in-doubt PostgreSQL 分支的示例:
$ oc rsh postgresql-2-vwf9n sh-4.2$ psql sampledb psql (9.5.7) Type "help" for help. psql sampledb commit prepared '131077_AAAAAAAAAAAAAP//rBEAB440GK1aJ72oAAAAGHAtanRh ---- LWNyYXNoLXJlYy0zLXAyY2N3_AAAAAAAAAAAAAP//rBEAB440GK1aJ72oAAAAGgAAAAEAAAAA';
重要
对所有数据源和 in-doubt 分支重复此步骤。