def transact(sql=nil, *args)
      # Work-around for rcbi nil substitution.
      if sql then
        sql, *args = replace_nil_binds(sql, args)
        transact { |dbh| dbh.execute(sql, *args) }
      elsif block_given? then
        execute { |dbh| dbh.transaction { yield dbh } }
      else
        raise ArgumentError.new("SQL executor is missing the required execution block")
      end
    end
def transact(sql=nil, *args)
      # Work-around for rcbi nil substitution.
      if sql then
        sql, *args = replace_nil_binds(sql, args)
        transact { |dbh| dbh.execute(sql, *args) }
      elsif block_given? then
        execute { |dbh| dbh.transaction { yield dbh } }
      else
        raise ArgumentError.new("SQL executor is missing the required execution block")
      end
    end
Runs the given SQL or block in a transaction. If SQL is provided, then that
 SQL is executed. Otherwise, the block is called.

 @quirk RDBI RDBI converts nil args to 12. Work-around this bug by embedding
   +NULL+ in the SQL instead.

 @param [String] sql the SQL to execute
 @param [Array] args the SQL bindings
 @yield [dbh] the transaction statements
 @yieldparam [RDBI::Database] dbh the database handle