保存失败后Rails没有回滚事务()

我有这个域模型:用户有一组项目,项目的状态可能无法通过validation。

validation工作正常,我甚至看到当我使用save!时调用exceptionsave!

在我的控制器中,我有这个:

 @user.items() < {}, :status => :ok else render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end 

第一个POST成功,第二个POST失败,但是当我点击索引时,我仍然看到两个对象,好像第二个事务从未回滚过。 到底是怎么回事?

我的测试是这样的:

  post :create post :create get :index ActiveSupport::JSON.decode(response.body).length.should == 1 

编辑:即使在运行服务器时,也不会回滚事务(sqlite3)。

将项添加到集合会立即保存它(除非用户未保存)。 对save的调用会创建自己的事务,即回滚的事务,而不是保存项目的事务

您可以通过显式创建一个来强制所有事务进入同一事务。

 begin User.transaction do @user.items << item @user.save! render :json => {}, :status => :ok end rescue ActiveRecord::RecordInvalid render :json => {:status => :error, :errors => item.errors}, :status => :bad_request end 

听起来你在测试中遇到了嵌套的事务问题。

我不相信Postgres的Ruby驱动程序处理嵌套事务,因此您只能获得外部事务的范围。 如果启用了事务夹具,则会有一个外部事务包装您的测试执行。 这意味着如果您的测试中的控制器创建了第二个内部事务,并尝试将其回滚 – 您可能无法获得正确的行为。

您可以通过关闭rspec中的事务来确认事务干扰:

 RSpec.configure do |config| config.use_transactional_fixtures = false end