Class: Dynamoid::TransactionRead
- Inherits:
-
Object
- Object
- Dynamoid::TransactionRead
- Defined in:
- lib/dynamoid/transaction_read.rb,
lib/dynamoid/transaction_read/find.rb
Overview
The class TransactionRead provides means to perform multiple reading
operations in transaction, that is atomically, so that either all of them
succeed, or all of them fail.
The reading methods are supposed to be as close as possible to their non-transactional counterparts:
user_id = params[:user_id]
payment = params[:payment_id]
models = Dynamoid::TransactionRead.execute do |t|
t.find User, user_id
t.find Payment, payment_id
end
The only difference is that the methods are called on a transaction
instance and a model or a model class should be specified. So User.find
becomes t.find(user_id) and Payment.find(payment_id) becomes +t.find
Payment, payment_id+.
A transaction can be used without a block. This way a transaction instance
should be instantiated and committed manually with #commit method:
t = Dynamoid::TransactionRead.new
t.find user_id
t.find payment_id
models = t.commit
DynamoDB's transactions
The main difference between DynamoDB transactions and a common interface is that DynamoDB's transactions are executed in batch. So in Dynamoid no data actually loaded when some transactional method (e.g+ `#find+) is called. All the changes are loaded at the end.
A TransactGetItems DynamoDB operation is used (see
documentation
for details).
Defined Under Namespace
Classes: Find
Class Method Summary collapse
Instance Method Summary collapse
-
#commit ⇒ Object
Load all the models.
-
#find(model_class, *ids, **options) ⇒ nil
Find one or many objects, specified by one id or an array of ids.
-
#initialize ⇒ TransactionRead
constructor
A new instance of TransactionRead.
Constructor Details
#initialize ⇒ TransactionRead
Returns a new instance of TransactionRead.
57 58 59 |
# File 'lib/dynamoid/transaction_read.rb', line 57 def initialize @actions = [] end |
Class Method Details
.execute ⇒ Object
48 49 50 51 52 53 54 55 |
# File 'lib/dynamoid/transaction_read.rb', line 48 def self.execute transaction = new begin yield transaction transaction.commit end end |
Instance Method Details
#commit ⇒ Object
Load all the models.
transaction = Dynamoid::TransactionRead.new
# ...
transaction.commit
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/dynamoid/transaction_read.rb', line 66 def commit return [] if @actions.empty? # some actions may produce multiple requests action_request_groups = @actions.map(&:action_request).map do |action_request| action_request.is_a?(Array) ? action_request : [action_request] end action_requests = action_request_groups.flatten(1) return [] if action_requests.empty? response = Dynamoid.adapter.transact_read_items(action_requests) responses = response.responses.dup @actions.zip(action_request_groups).map do |action, action_requests| action_responses = responses.shift(action_requests.size) action.process_responses(action_responses) end.flatten end |
#find(model_class, *ids, **options) ⇒ nil
Find one or many objects, specified by one id or an array of ids.
By default it raises RecordNotFound exception if at least one model
isn't found. This behavior can be changed with raise_error option. If
specified raise_error: false option then find will not raise the
exception.
When a document schema includes range key it should always be specified
in find method call. In case it's missing MissingRangeKey exception
will be raised.
Please note that there are the following differences between
transactional and non-transactional find:
- transactional
findpreserves order of models in result when given multiple ids - transactional
finddoesn't return results immediately, a single collection with results of all thefindcalls is returned instead :consistent_readoption isn't supported- transactional
findis subject to limitations of the TransactGetItems DynamoDB operation, e.g. the whole read transaction can load only up to 100 models.
133 134 135 136 |
# File 'lib/dynamoid/transaction_read.rb', line 133 def find(model_class, *ids, **) action = Dynamoid::TransactionRead::Find.new(model_class, *ids, **) register_action action end |