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

database/gdb: In the transaction, the Schema method does not take effect and the corresponding table structure cannot be obtained correctly. #3876

Open
yimuysl001 opened this issue Oct 21, 2024 · 6 comments
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.

Comments

@yimuysl001
Copy link

Go version

go1.20.14 windows/amd64

GoFrame version

2.7.4

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

复现bug代码:

1.表结构

use BAK -- 分别在一个数据源当中的不同数据库中创建表格
create table TBA(
	id int,
	name varchar(10),
) 
use ELT -- 分别在一个数据源当中的不同数据库中创建表格
create table TBB(
	id int,
	name varchar(10),
) 

2.使用tx事务问题

func main() {
	err := g.DB("local").Transaction(gctx.New(), func(ctx context.Context, tx gdb.TX) error {
        // local 配置使用连接用的其他库
        // 使用 Schema 未能正常切换到相应的库当中
		_, err := tx.Model("TBA").Schema("BAK").Insert(map[string]interface{}{
			"id":   1,
			"name": "aaa",
		})
		if err != nil {
			return err
		}

		_, err = tx.Model("TBB").Schema("ELT").Insert(map[string]interface{}{
			"id":   1,
			"name": "aaa",
		})
		return err
	})

	fmt.Println(err) // 报错 The table "TBA" may not exist, or the table contains no fields
}    

3.使用ctx 事务

func main() {
	err := g.DB("local").Transaction(gctx.New(), func(ctx context.Context, tx gdb.TX) error {
        // local 配置使用连接用的其他库
        // 使用 Schema 未能正常切换到相应的库当中
		_, err := g.DB("local").Ctx(ctx).Model("TBA").Schema("BAK").Insert(map[string]interface{}{
			"id":   1,
			"name": "aaa",
		})
		if err != nil {
			return err
		}
		_, err = g.DB("local").Ctx(ctx).Model("TBB").Schema("ELT").Insert(map[string]interface{}{
			"id":   1,
			"name": "aaa",
		})
		return err
	})
	fmt.Println(err) // 报错 The table "TBA" may not exist, or the table contains no fields
}
  1. Schema在Model前面

    func main() {
    
    	err := g.DB("local").Transaction(gctx.New(), func(ctx context.Context, tx gdb.TX) error {
            // 切换了 Model 与 Schema 的位置
    		_, err := g.DB("local").Ctx(ctx).Schema("BAK").Model("TBA").Insert(map[string]interface{}{
    			"id":   1,
    			"name": "aaa",
    		})
    		if err != nil {
    			return err
    		}
    
    		_, err = g.DB("local").Ctx(ctx).Schema("ELT").Model("TBB").Insert(map[string]interface{}{
    			"id":   1,
    			"name": "aaa",
    		})
    		return err
    	})
    	fmt.Println(err) // 数据保存成功,但是不是在事务中保存的,而是单独新链接保存的数据,事务中间报错无法回滚数据
    }

What did you see happen?

如果数据涉及到分库分表,需要在一个数据源跨库进行数据增删改查的操作,目前使用gdb的事务,一个事务只能在一个库中进行操作,无法有效获取数据源其他库的表结构,无法保存数据

What did you expect to see?

希望能在事务中提供类似Schema的方法,让数据能够正常处理;或者提供一个方法,如果没查到表结构,使用需要提交map的key来做数据的字段(目前是直接报错,无法在model(aaa..bbb)的方式强制切换库)

@yimuysl001 yimuysl001 added the bug It is confirmed a bug, but don't worry, we'll handle it. label Oct 21, 2024
@Issues-translate-bot Issues-translate-bot changed the title database/gdb: issue title 事务当中,Schema 方法不生效,无法正确获取到相应的表结构。 database/gdb: issue title In the transaction, the Schema method does not take effect and the corresponding table structure cannot be obtained correctly. Oct 21, 2024
@UncleChair
Copy link
Contributor

应该不算是bug,之前有看到过 #3820 这个issue的回复

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


It should not be considered a bug. I have seen the [reply] of this issue #3820 before (#3820 (comment))

@yimuysl001
Copy link
Author

@UncleChair 如果不支持跨库,能直接用.model(tableName) 和data 拼接sql也行呀,现在是如果没查到表字段直接报错,至少是希望如果没查到表字段,直接使用data里面的key,表明直接使用 传的tableName.

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@UncleChair If cross-database support is not supported, you can directly use .model(tableName) and data to splice sql. Now, if the table field is not found, an error will be reported directly. At least I hope that if the table field is not found, you can directly use the data in the data. key, indicating that the passed tableName is used directly.

@gqcn
Copy link
Member

gqcn commented Oct 24, 2024

@UncleChair 如果不支持跨库,能直接用.model(tableName) 和data 拼接sql也行呀,现在是如果没查到表字段直接报错,至少是希望如果没查到表字段,直接使用data里面的key,表明直接使用 传的tableName.

@yimuysl001 你好,我理解数据库应该本身不支持跨库的?所以Schema数据库切换实际上是没有保存之前的事务链接的。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@UncleChair If cross-database support is not supported, you can directly use .model(tableName) and data to splice sql. Now, if a table field is not found, an error will be reported directly. At least I hope that if a table field is not found, it can be directly used in data. The key indicates that the passed tableName is used directly.

@yimuysl001 Hello, I understand that the database itself does not support cross-database? Therefore, Schema database switching does not actually save the previous transaction links.

@gqcn gqcn changed the title database/gdb: issue title In the transaction, the Schema method does not take effect and the corresponding table structure cannot be obtained correctly. database/gdb: In the transaction, the Schema method does not take effect and the corresponding table structure cannot be obtained correctly. Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.
Projects
None yet
Development

No branches or pull requests

4 participants