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](docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html) 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
find
preserves order of models in result when given multiple ids -
transactional
find
doesn’t return results immediately, a single collection with results of all thefind
calls is returned instead -
:consistent_read
option isn’t supported -
transactional
find
is subject to limitations of the [TransactGetItems](docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html) 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 |