使用Authlogic和Rails进行竞争条件4.1.1

时间:2014-05-18 00:44:57

标签: ruby-on-rails postgresql ruby-on-rails-4 race-condition

我正在将应用程序升级到rails 4.1.1和authlogic 3.4.2,并在集成测试中遇到竞争条件问题。

我有一个页面在加载时发出两个ajax请求。这两个请求都会导致authlogic尝试更新登录用户记录的last_request_at列。我并不总是得到相同的异常,但是当应用程序尝试连续更新相同的用户记录时,总会引发异常。

这不是rails 3上的问题,因为他们在测试环境中使用了Rack :: Lock。

以下是日志片段:

User Load (0.6ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 2 LIMIT 1                                                                  [50/1923]
  User Load (0.8ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 2 LIMIT 1
   (1.5ms)  BEGIN
   (0.2ms)  BEGIN
  SQL (0.3ms)  UPDATE "users" SET "last_request_at" = $1, "perishable_token" = $2, "updated_at" = $3 WHERE "users"."type" IN ('MedicalProfessional') AND "user
s"."id" = 2  [["last_request_at", "2014-05-18 00:19:46.564174"], ["perishable_token", "awlh6mBgHl2mdU2uboi"], ["updated_at", "2014-05-18 00:19:46.566315"]]
PG::Error: another command is already in progress
: UPDATE "users" SET "last_request_at" = $1, "perishable_token" = $2, "updated_at" = $3 WHERE "users"."type" IN ('MedicalProfessional') AND "users"."id" = 2
  SQL (1.7ms)  UPDATE "users" SET "last_request_at" = $1, "perishable_token" = $2, "updated_at" = $3 WHERE "users"."type" IN ('MedicalProfessional') AND "user
s"."id" = 2  [["last_request_at", "2014-05-18 00:19:46.562637"], ["perishable_token", "SoXbKuCMs0Zu3vtxKGqn"], ["updated_at", "2014-05-18 00:19:46.564956"]]
   (0.2ms)  ROLLBACK
Completed 500 Internal Server Error in 132ms
   (0.5ms)  COMMIT

ActiveRecord::StatementInvalid (PG::Error: another command is already in progress
: UPDATE "users" SET "last_request_at" = $1, "perishable_token" = $2, "updated_at" = $3 WHERE "users"."type" IN ('MedicalProfessional') AND "users"."id" = 2):
  app/helpers/auth_helper.rb:3:in `current_user_session'
  app/helpers/auth_helper.rb:7:in `current_user'

我应该如何/可以解决此问题?

1 个答案:

答案 0 :(得分:0)

原来,我的团队中的其他人已经修补了ActiveRecord,以便所有线程使用相同的数据库连接以加快测试速度。他从中得到了这个想法:http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/

我能够通过在失败的测试开始时设置ActiveRecord :: Base.shared_connection = nil来解决这个问题。