Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seata1.7.0 AT模式 对于日期为主键的表没有生成undolog,导致报错后无法回滚。 #7006

Open
1 task
songfz123 opened this issue Nov 15, 2024 · 5 comments

Comments

@songfz123
Copy link

songfz123 commented Nov 15, 2024

  • I have searched the issues of this repository and believe that this is not a duplicate.

Ⅰ. Issue Description

未生成undolog日志信息,也没有在lock_table表产生数据。以至于后续报错也不会回滚

Ⅱ. Describe what happened

有这么两张表,test_c 表为id主键表, test_d表为日期为主键表
CREATE TABLE test_c (
id bigint(22) NOT NULL AUTO_INCREMENT,
create_time datetime DEFAULT NULL,
test varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (id)
) AUTO_INCREMENT = 1000001 DEFAULT CHARSET = utf8mb4

CREATE TABLE test_d (
id bigint(22) NOT NULL AUTO_INCREMENT,
create_time datetime NOT NULL,
test varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (create_time)
) AUTO_INCREMENT = 1000001 DEFAULT CHARSET = utf8mb4

a服务调用b服务,而b服务中插入这两个表,两个表在同一个事务中。
image

image
当产生undolog时,只有test_c 表产生了日志,test_d 表未生成日志。
image
lock_table表也只产生了test_c 表的主键信息。

当a服务调用b服务结束后返回时,a服务抛出一个异常,此时只有test_c表会进行回滚,test_d表不会进行回滚。
image

Ⅲ. Describe what you expected to happen

我希望能让test_d表一起跟普通id主键表一样产生undolog,当出现后续异常时可以一起进行回滚事务。

Ⅳ. How to reproduce it (as minimally and precisely as possible)

代码参考上述截图,简单的测试,a服务通过feign调用b服务,b服务插入这两个表,调用返回后,a服务抛出异常即可复现。

Ⅴ. Anything else we need to know?

以上问题希望能够通过seata方面进行解决,目前出现问题的业务表在生产环境上数据量较大且不支持直接修改主键类型或修改索引类型。

Ⅵ. Environment:

  • JDK version(e.g. java -version): jdk1.8
  • Seata client/server version: v1.7.0
  • Database version: oceanBase数据库mysql模式 商业版本 3.2.2
  • OS(e.g. uname -a):
  • Others:
@slievrly
Copy link
Member

When checking the data in the undo_log table, confirm that the local transaction corresponding to test_d has been committed.
Seeing that your code above refers to Transactional and GlobalTransactional together, this is a fine use, but it is not easy to debug and view undo_log data.

@songfz123
Copy link
Author

songfz123 commented Nov 18, 2024

When checking the data in the undo_log table, confirm that the local transaction corresponding to test_d has been committed. Seeing that your code above refers to Transactional and GlobalTransactional together, this is a fine use, but it is not easy to debug and view undo_log data.

是的,test_c表和test_d表都已提交,根据断点结果,在后续步骤抛出异常之前,两个表的数据都已经插入到表中
image
image

@ygg100
Copy link

ygg100 commented Dec 14, 2024

@songfz123
我也遇到同样问题。
联合主键 (id,create_time)也会导致undolog无法创建

临时解决方案:
把create_time date 类型改成data可解决此问题

@GoodBoyCoder
Copy link
Contributor

如果Java内Date类型的字段,数据库是datetime类型,两者的精度对不上的话就会查询不到对应数据,也就无法生成后镜像,前后镜像都为空的情况undoLog就不会生成。举个例子,数据库内只存了秒的精度(2025-01-05 10:10:10),Java内Date类型则是精确到毫秒(2025-01-05 10:10:10.924),用毫秒的条件去查询就会匹配不到数据。这个场景下设置数据库datetime的精度到毫秒datetime(3)可以解决问题,或者推荐使用timestamp类型。还有可能的场景,mybatis下可以设置字段类型为Date类型,在插入数据的时候会将Java内Date类型截断到日期,保存到数据库的时候也是只到日期,而Seata拿到的日期则是包含时分秒的,两者也会匹配不上

@lbj812
Copy link

lbj812 commented Jan 6, 2025

datetime(3)可以解决问题,测试通过,完美

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants