Rails 6测试环境多数据库副本功能异常问题排查
排查Rails 6测试环境多数据库角色切换返回空的问题
1. 测试事务隔离导致副本连接读不到数据
Rails默认测试启用use_transactional_fixtures,每个测试用事务包裹主库写入操作。由于副本库的连接是独立的数据库连接,无法读取未提交事务内的数据,因此切换到reading角色后查询返回空。
解决办法:
禁用事务测试,改用截断表清理数据:在
test_helper.rb中修改配置:class ActiveSupport::TestCase self.use_transactional_fixtures = false setup do DatabaseCleaner.strategy = :truncation DatabaseCleaner.start end teardown do DatabaseCleaner.clean end end需先添加
database_cleanergem到测试环境。若副本与主库为同一数据库,可强制复用主库连接的事务上下文:
ActiveRecord::Base.connected_to(role: :reading, shard: :default, prevent_writes: true) do ActiveRecord::Base.connection.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED") # 执行查询逻辑 end
2. 检查副本库配置是否标记为replica
确保database.yml中测试环境的副本库配置添加replica: true,否则Rails无法正确识别其副本角色,可能导致连接逻辑异常:
test: primary: adapter: postgresql database: my_app_test # 其他主库配置项 primary_replica: adapter: postgresql database: my_app_test replica: true # 其他副本库配置(与主库一致) third_replica: adapter: postgresql database: my_app_test replica: true # 其他副本库配置
3. 验证连接切换后的数据库指向
在测试中添加调试代码,确认切换角色后连接的数据库是否正确:
test "verify reading role connection" do # 主库连接信息 puts "Writing role database: #{ActiveRecord::Base.connection.current_database}" puts "Writing role count: #{Model.count}" # 切换至reading角色后检查 ActiveRecord::Base.connected_to(role: :reading, shard: :default, prevent_writes: true) do puts "Reading role database: #{ActiveRecord::Base.connection.current_database}" puts "Reading role count: #{Model.count}" end end
若输出显示reading角色连接的数据库与主库不一致,需修正database.yml中副本库的数据库名称配置。
4. 检查测试数据加载方式
如果测试数据通过fixtures或seeds加载,需确保数据已提交到数据库(而非仅在事务内)。例如启用事务测试时,fixtures数据会被包裹在事务中,副本连接无法读取,此时可改用before(:all)加载数据并提交事务,或直接禁用事务测试。
内容的提问来源于stack exchange,提问作者Laurent
相关产品推荐
相关产品推荐

