• Rails 中的事物处理


    1. 使用事物的原因

    保证数据一致性, 当其中出现一个失败的时候,操作可以回滚

    比如:

    ActiveRecord::Base.transaction do 
        david.withdrawal(100) # withdrawal失败必须触发 exception
        mary.deposit(100) # deposit失败必须触发 exception
    end

    return false 不会出发操作回滚, 所以事物中要使用!的方法, 比如 save! update!

    before_save 等callback也包含在事物中, 如果希望触发事物回滚, 需要能抛出异常

    如果不希回滚则不抛出异常 或者放在事物之外 用after_commit等callbacl来处理

    事务陷阱

    不要在事务内部去捕捉 ActiveRecord::RecordInvalid 异常。因为某些数据库下,这个异常会导致事务失效,比如 Postgres。一旦事务失效,要想让代码正确工作,就必须从头重新执行事务。

    另外,测试回滚或者事务回滚相关的回调时,最好关掉 transactional_fixtures 选项,一般的测试框架中,这个选项是打开的。

    常见的事务反模式

    1. 单条记录操作时使用事务
    2. 不必要的使用嵌套式事务
    3. 事务中的代码不会导致回滚
    4. 在 controller 中使用事务

    Exception handling and rolling back (待翻译)

    Also have in mind that exceptions thrown within a transaction block will be propagated (after triggering the ROLLBACK), so you should be ready to catch those in your application code.

    One exception is the ActiveRecord::Rollback exception, which will trigger a ROLLBACK when raised, but not be re-raised by the transaction block.

    Warning: one should not catch ActiveRecord::StatementInvalid exceptions inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an error occurred at the database level, for example when a unique constraint is violated. On some database systems, such as PostgreSQL, database errors inside a transaction cause the entire transaction to become unusable until it's restarted from the beginning. Here is an example which demonstrates the problem:

    # Suppose that we have a Number model with a unique column called 'i'.
    Number.transaction do
      Number.create(i: 0)
      begin
        # This will raise a unique constraint error...
        Number.create(i: 0)
      rescue ActiveRecord::StatementInvalid
        # ...which we ignore.
      end
    
      # On PostgreSQL, the transaction is now unusable. The following
      # statement will cause a PostgreSQL error, even though the unique
      # constraint is no longer violated:
      Number.create(i: 1)
      # => "PGError: ERROR:  current transaction is aborted, commands
      #     ignored until end of transaction block"
    end
  • 相关阅读:
    软件项目的需求变更管理
    便利店规模经营的条件是什么?
    店长不得不知的七类非语言沟通方式
    软件项目管理的十大定律
    零售业精细化管理必须做好三大源头
    超市货架陈列暗藏玄机 最新鲜的藏在最后面
    超市陈列原则
    店铺中货架的装修设计要点
    《图解Java多线程设计模式》之五:Balking 模式
    《图解Java多线程设计模式》之三:Immutable 模式
  • 原文地址:https://www.cnblogs.com/angelfan/p/5208540.html
Copyright © 2020-2023  润新知