首页 \ 问答 \ 保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())

保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())

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

验证工作正常,我甚至看到当我使用save!时调用异常save!

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

@user.items() << item

if @user.save
  render :json => {}, :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)。


I have this domain model: A user has group of items, and the state of the items can fail a validation.

Validation works fine, and I even see exceptions get called when I use save!.

In my controller, I have this:

@user.items() << item

if @user.save
  render :json => {}, :status => :ok
else
  render :json => {:status => :error, :errors => item.errors}, :status => :bad_request
end

The first POST succeeds, and the second POST fails, but when I hit the index, I still see two objects, as if the second transaction never rolled back. What is going on?

My test is this:

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

Edit: Even when running a server, transactions are not being rolled back (sqlite3).


原文:https://stackoverflow.com/questions/14665269
更新时间:2020-11-02 18:11

最满意答案

将项添加到集合会立即保存它(除非用户未保存)。 对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

Adding an item to the collection saves it immediately (unless the user is unsaved). The call to save creates its own transaction and that is what is rolled back, not the transaction in which the item is saved

You could force everything into the same transaction by creating one explicitly.

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

相关问答

更多

回滚失败的Rails迁移(Rolling back a failed Rails migration)

不幸的是,您必须手动清理MySQL的失败迁移。 MySQL不支持事务数据库定义更改。 Rails 2.2包括PostgreSQL的事务迁移。 Rails 2.3包括SQLite的事务迁移。 这不是真的有助于您解决您的问题,但如果您在未来的项目中选择了数据库,我建议使用支持事务DDL的一个,因为它使迁移更加愉快。 更新 - 这仍然是在2017年,在Rails 4.2.7和MySQL 5.7,由Alejandro Babio在另一个答复报道。 Unfortunately, you must manua ...

hibernate事务没有正确回滚(hibernate transaction not rolling back correctly)

交易不是“级联”。 在JDBC级别,事务包括: 关闭自动提交 执行一些陈述 调用java.sql.Connection.commit()或java.sql.Connection.rollback() 。 如果你说有些东西正在提交而有些东西被回滚,那么你的交易管理就会出现问题。 自动提交已启用或您实际上有多次调用commit()正在发生。 Transactions don't "cascade". At the JDBC level, a transaction consists of: Turni ...

为什么我的MSDTC事务无法在本地主机环境中正确回滚?(Why is my MSDTC transaction not correctly rolling back on my localhost environment?)

用户Pankaj Kapare提供的链接对解决这个问题非常有帮助。 基本上,我并没有真正将在控制台应用程序(根交易管理器)中初始化的交易传递给任何web api应用程序(这应该是显而易见的)。 因此,每个web api应用程序都初始化自己的事务,而不是参与现有的事务。 总结链接时,控制台应用程序中初始化的主要事务可以使用TransactionInterop作为标记检索,并作为请求标头或Cookie的一部分传递给Webapi: if (Transaction.Current != null) { ...

使用Spring回滚事务 - AOP(Rolling back Transaction with Spring - AOP)

尝试更改您的AOP表达式以包括服务接口(如果它们未被覆盖)。 我遇到的问题是我的服务接口与服务实现位于不同的包中,如果它们未被AOP表达式覆盖,则不会启动/提交/滚动事务。 此外,如果这是一个webapp,请考虑删除AOP以支持Spring的OpenSessionInViewFilter ,它会在请求进入时打开会话,并在返回/抛出后提交/回滚它。 最后,我使用了具有出色Spring支持的IntelliJ IDE - 您可以在XML文件中单击AOP声明,并查看模式匹配的所有方法的弹出列表 - 真正有 ...

实体框架5 SaveChanges()不回滚尝试的事务(Entity Framework 5 SaveChanges() not rolling back attempted transaction)

这是预期的行为。 SaveChanges尝试在单个数据库事务中提交所有更改。 如果失败,则回滚数据库事务,并且不会将任何内容写入数据库。 但失败的事务不会改变上下文中实体的状态。 这就是你的Setting实体仍然处于状态的原因。 将Error实体附加到同一上下文是一个问题,因为您通常无法将其存储到数据库中,就像在此示例中一样。 我会考虑始终在新的上下文中使用专用方法编写错误日志,该方法仅打开新上下文,将Error实体添加到此上下文并保存更改。 然后立即处理它。 This is expected b ...

MySQL事务没有回滚错误(MySQL transaction not rolling back on error)

这是我在我的存储过程中使用的一个对我有用的事务。 DECLARE exit handler for sqlexception BEGIN -- ERROR SHOW ERRORS; ROLLBACK; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING SHOW WARNINGS; ROLLBACK; END; 更多信息可以在这里找到 htt ...

Spring @Transaction没有回滚(Spring @Transaction not rolling back)

从您的配置判断您正在使用Hibernate,但是您使用的事务管理器仅用于纯JDBC使用。 要进行适当的事务管理,必须使用属于持久性技术的PlatformTransactionManager 。 在您的情况下,您应该使用HibernateTransactionManager而不是DataSourceTransactionManager 。 <bean id="transactionManager" class="org.springframework.hibernate5.HibernateTran ...

防止内部事务回滚外部事务(Prevent inner transaction from rolling back outer transaction)

您可以在新事务中运行有问题的方法。 而不是@Transactional(propagation = Propagation.NOT_SUPPORTED) ,您应该使用Propagation.REQUIRES_NEW : @Transactional(propagation = Propagation.REQUIRES_NEW) 强制创建新事务。 NOT_SUPPORTED不会导致创建新事务,它只会暂停当前事务。 在try / catch块中包含对方法的调用。 我不确定你在春天的环境中会得到什么样的 ...

PHP事务没有回滚(PHP transaction not rolling back)

猜猜你的桌子没有使用合适的引擎 http://php.net/mysqli.autocommit 此函数不适用于非事务表类型(如MyISAM或ISAM)。 但是,使用INSERT IGNORE (或REPLACE取决于应该是正确的行为)要容易得多。 在这种情况下,将以静默方式忽略重复的行(或替换现有的行( REPLACE ))。 当然,如果您想知道哪些是重复的,这不起作用。 Guess your tables doesn't use an appropriate engine http://php ...

保存失败后Rails没有回滚事务()(Rails not rolling back transaction after failed save())

将项添加到集合会立即保存它(除非用户未保存)。 对save的调用会创建自己的事务,即回滚的事务,而不是保存项目的事务 您可以通过显式创建一个来强制所有事务进入同一事务。 begin User.transaction do @user.items << item @user.save! render :json => {}, :status => :ok end rescue ActiveRecord::RecordInvalid render :json => ...

相关文章

更多

最新问答

更多
  • 如何从远程文件拉取文件而不覆盖本地文件?(How do I pull files from remote without overwriting local files?)
  • Reactjs:状态改变时重新渲染iframe(Reactjs: re-renders iframes when state changed)
  • 奇怪的网址,以及跟随php页面流程的困难(odd url, and difficulty in following the php page flow)
  • 标签活动无效(Tab Activity is not working)
  • JavaME合适的语法编译器建议?(JavaME-suitable grammar compiler recommendations?)
  • 指定参数(Specifying arguments)
  • 可以通过Ruby插件或控制台覆盖Sketchup中的键盘快捷键吗?(Can one override keyboard shortcuts in Sketchup through the a Ruby Plugin or Console?)
  • 计算Java EE Web App中用户数的最佳方法(Best way to count number of users in a Java EE web App)
  • 无法使用templateUrl加载cordova中的外部模板(unable to load external templates in cordova with templateUrl)
  • PHPExcel:写入期间无法使用缓存(PHPExcel: Unable to use cache during write)
  • 在javascript中嵌套这个指针(nested this pointer in javascript)
  • 谁跟领航致远培训过,有问题问下啊
  • 控制器要求在入门时下载(Controller ask to download on entry)
  • 未能通过conda安装Asyncio(Failure to install Asyncio via conda)
  • 如何查找已完成项目的总长度?(How to find length of total completed items?)
  • 如何检查OleInitialize是否已被调用?(How to check if OleInitialize has already been called?)
  • SQL在特定范围内返回列中具有最大值的行(SQL Returning rows with max value in column, within a specific range)
  • preg_match从url获取id(preg_match get the id from url)
  • 如何在运算符中为make方程转换perl变量?(How to convert a perl variable in a operator for make equations?)
  • 在导航上方添加空格/标题。(Add a white space/ header above navigation.)
  • MeetingItem已保存;(MeetingItem saved; but change now shown in Calendar)
  • c#vb:我们应该使用System.Lazy进行资源密集型任务吗?(c# vb: Should we use System.Lazy for resource-intensive task? (when threading is not needed))
  • 为什么在armeabi代码中使用armeabi-v7a代码?(Why use armeabi-v7a code over armeabi code?)
  • 获取请求的自定义标头(Java HTTP)(Fetching a custom header of a request (Java HTTP))
  • 是否可以在嵌套的if语句中从varchar转换为numeric以动态评估参数?(Is it possible to convert from varchar to numeric within a nested if statement in order to dynamically evaluate a parameter?)
  • 如何将Html.ActionLink转换为链接到Ajax调用的按钮?(How to convert from Html.ActionLink to a button linked to Ajax call?)
  • 应用程序如何处理Windows符号链接?(How are Windows symbolic links treated by the apps?)
  • html,js,css在jsfiddle中工作,但不在sharepoint中(html, js, css works in jsfiddle but not in sharepoint)
  • 从Ruby脚本调用Elasticsearch Rest API(Calling Elasticsearch Rest API from Ruby script)
  • 如何将嵌套setTimeouts转换为承诺(How to convert nested setTimeouts to promises)