内容来自 rails 官方,可直接观看。
提炼出一下知识点:
- 事务是基于数据库连接,不是基于模型的 (transactions are per-database connection, not per-model)
- 可以基于模型的类 model class 或者模型的实例 model instance,或者用 ActiveRecord::Base
- 基于上面两点,事务的编写可以不用 ActiveRecord::Base,而是根据当前的代码,拿当前模型的类或者实例即可。
- 事务不会跨数据库连接传播 (Transactions are not distributed across database connections)
- save,destroy 自动的嵌套了事务,所有的 callbacks 在事务中,包括 after_*的回调。所以 after_save 后抛异常,也会回滚
- 异常
- ActiveRecord::StatementInvalid 此异常抛出后,数据库连接已经断开,以后的数据库操作都将无法进行
- ActiveRecord::Rollback 会被当前事务捕获,触发一次回滚,但是不会被再次抛出异常
- 其他的异常抛出后,会触发回滚
- 嵌套事务
- 默认使用最外层的那个事务
- 除 ms-sql 外,其他数据库并不支持真正的嵌套事务,用 savepoint 来实现的
- 嵌套事务中,假如不指定 requires_new: true,那么嵌套部分事务,是最外层事务的一部分,并不是一个真正的事务
- ActiveRecord::Rollback 在嵌套事务中的效果:
- 没有 requires_new: true,那么当前事务 (非真正的事务) 捕获,并且不会再次抛出异常,则外层的真正事务会执行,并且嵌套部分也没有回滚,而是被数据库保存。
- requires_new: true 后,当前事务会回滚,最外层事务在没有其他异常时不会回滚。
- 非 ActiveRecord::Rollback 的异常,无论是否在嵌套内,都会被传播,最终引发回滚
暂无回复。