Skip to content

Commit c94c76b

Browse files
RUBY-5530 Add transaction method to Mongoid module (#5517)
1 parent d42403f commit c94c76b

File tree

2 files changed

+106
-69
lines changed

2 files changed

+106
-69
lines changed

lib/mongoid.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module Mongoid
4242
extend Forwardable
4343
extend Loggable
4444
extend self
45+
extend Clients::Sessions::ClassMethods
4546

4647
# A string added to the platform details of Ruby driver client handshake documents.
4748
PLATFORM_DETAILS = "mongoid-#{VERSION}".freeze
@@ -113,6 +114,21 @@ def client(name)
113114
# Mongoid.database = Mongo::Connection.new.db("test")
114115
def_delegators Config, *(Config.public_instance_methods(false) - [ :logger=, :logger ])
115116

117+
# Define persistence context that is used when a transaction method is called
118+
# on Mongoid module.
119+
#
120+
# @api private
121+
def persistence_context
122+
PersistenceContext.get(Mongoid) || PersistenceContext.new(Mongoid)
123+
end
124+
125+
# Define client that is used when a transaction method is called
126+
# on Mongoid module. This MUST be the default client.
127+
#
128+
# @api private
129+
def storage_options
130+
{ client: :default }
131+
end
116132

117133
# Module used to prepend the discriminator key assignment function to change
118134
# the value assigned to the discriminator key to a string.

spec/mongoid/clients/transactions_spec.rb

Lines changed: 90 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
require "spec_helper"
44

5+
def capture_exception
6+
e = nil
7+
begin
8+
yield
9+
rescue => ex
10+
e = ex
11+
end
12+
e
13+
end
14+
515
describe Mongoid::Clients::Sessions do
616
before(:all) do
717
if Gem::Version.new(Mongo::VERSION) < Gem::Version.new('2.6')
@@ -200,37 +210,29 @@
200210

201211
context 'using #with_session' do
202212
let!(:error) do
203-
e = nil
204-
begin
213+
capture_exception do
205214
Person.with_session do |s|
206215
s.start_transaction
207216
Person.create!
208217
Person.create!
209218
Post.create!
210219
s.commit_transaction
211220
end
212-
rescue => ex
213-
e = ex
214221
end
215-
e
216222
end
217223

218224
include_examples 'it does not abort the transaction'
219225
end
220226

221227
context 'using #transaction' do
222228
let!(:error) do
223-
e = nil
224-
begin
229+
capture_exception do
225230
Person.transaction do
226231
Person.create!
227232
Person.create!
228233
Post.create!
229234
end
230-
rescue => ex
231-
e = ex
232235
end
233-
e
234236
end
235237

236238
include_examples 'it does not abort the transaction'
@@ -252,38 +254,30 @@
252254

253255
context 'using #with_session' do
254256
let!(:error) do
255-
e = nil
256-
begin
257+
capture_exception do
257258
Person.with_session do |s|
258259
s.start_transaction
259260
s.start_transaction
260261
Person.create!
261262
Post.create!
262263
s.commit_transaction
263264
end
264-
rescue => ex
265-
e = ex
266265
end
267-
e
268266
end
269267

270268
include_examples 'it aborts the transaction', Mongo::Error::InvalidTransactionOperation
271269
end
272270

273271
context 'using #transaction' do
274272
let!(:error) do
275-
e = nil
276-
begin
273+
capture_exception do
277274
Person.transaction do
278275
Person.transaction do
279276
Person.create!
280277
Post.create!
281278
end
282279
end
283-
rescue => ex
284-
e = ex
285280
end
286-
e
287281
end
288282

289283
include_examples 'it aborts the transaction', Mongoid::Errors::InvalidTransactionNesting
@@ -331,16 +325,12 @@
331325

332326
context 'when Mongoid::Errors:Rollback raised' do
333327
let!(:error) do
334-
error = nil
335-
begin
328+
capture_exception do
336329
Person.transaction do
337330
Person.create!
338331
raise Mongoid::Errors::Rollback
339332
end
340-
rescue => e
341-
error = e
342333
end
343-
error
344334
end
345335

346336
it 'does not bass on the exception' do
@@ -368,33 +358,25 @@
368358

369359
context 'using #with_session' do
370360
let!(:error) do
371-
e = nil
372-
begin
361+
capture_exception do
373362
Person.with_session do |s|
374363
s.start_transaction
375364
Person.create!
376365
s.commit_transaction
377366
end
378-
rescue => ex
379-
e = ex
380367
end
381-
e
382368
end
383369

384370
include_examples 'it raises a transactions not supported error'
385371
end
386372

387373
context 'using #transaction' do
388374
let!(:error) do
389-
e = nil
390-
begin
375+
capture_exception do
391376
Person.transaction do
392377
Person.create!
393378
end
394-
rescue => ex
395-
e = ex
396379
end
397-
e
398380
end
399381

400382
include_examples 'it raises a transactions not supported error'
@@ -537,37 +519,30 @@
537519

538520
context 'using #with_session' do
539521
let!(:error) do
540-
e = nil
541-
begin
522+
capture_exception do
542523
person.with_session do |s|
543524
s.start_transaction
544525
person.username = 'Emily'
545526
person.save!
546527
person.posts << Post.create!
547528
s.commit_transaction
548529
end
549-
rescue => ex
550-
e = ex
551530
end
552-
e
553531
end
554532

555533
include_examples 'does not abort the transaction'
556534
end
557535

558536
context 'using #transaction' do
559537
let!(:error) do
560-
e = nil
561-
begin
538+
capture_exception do
562539
person.transaction do
563540
person.username = 'Emily'
564541
person.save!
565542
person.posts << Post.create!
566543
end
567544
rescue => ex
568-
e = ex
569545
end
570-
e
571546
end
572547

573548
include_examples 'does not abort the transaction'
@@ -577,8 +552,7 @@
577552
context 'when transactions are nested' do
578553
context 'use #with_session' do
579554
let!(:error) do
580-
e = nil
581-
begin
555+
capture_exception do
582556
person.with_session do |s|
583557
s.start_transaction
584558
s.start_transaction
@@ -587,10 +561,7 @@
587561
person.posts << Post.create!
588562
s.commit_transaction
589563
end
590-
rescue => ex
591-
e = ex
592564
end
593-
e
594565
end
595566

596567
it 'raises an error' do
@@ -606,19 +577,15 @@
606577

607578
context 'use #transaction' do
608579
let!(:error) do
609-
e = nil
610-
begin
580+
capture_exception do
611581
person.transaction do
612582
person.transaction do
613583
person.username = 'Emily'
614584
person.save!
615585
person.posts << Post.create!
616586
end
617587
end
618-
rescue => ex
619-
e = ex
620588
end
621-
e
622589
end
623590

624591
it 'raises an error' do
@@ -637,17 +604,13 @@
637604

638605
context 'when Mongoid::Errors:Rollback raised' do
639606
let!(:error) do
640-
error = nil
641-
begin
607+
capture_exception do
642608
person.transaction do
643609
person.username = 'John'
644610
person.save!
645611
raise Mongoid::Errors::Rollback
646612
end
647-
rescue => e
648-
error = e
649613
end
650-
error
651614
end
652615

653616
it 'does not bass on the exception' do
@@ -682,18 +645,14 @@
682645

683646
context 'using #with_session' do
684647
let!(:error) do
685-
e = nil
686-
begin
648+
capture_exception do
687649
person.with_session do |s|
688650
s.start_transaction
689651
person.username = 'Emily'
690652
person.save!
691653
s.commit_transaction
692654
end
693-
rescue => ex
694-
e = ex
695655
end
696-
e
697656
end
698657

699658
it 'raises a transactions not supported error' do
@@ -704,16 +663,12 @@
704663

705664
context 'using #transaction' do
706665
let!(:error) do
707-
e = nil
708-
begin
666+
capture_exception do
709667
person.transaction do
710668
person.username = 'Emily'
711669
person.save!
712670
end
713-
rescue => ex
714-
e = ex
715671
end
716-
e
717672
end
718673

719674
it 'raises a transactions not supported error' do
@@ -735,4 +690,70 @@
735690
end
736691
end
737692
end
693+
694+
context 'when a transaction is used on Mongoid module' do
695+
let(:subscriber) do
696+
Mongoid::Clients.with_name(:default).send(:monitoring).subscribers['Command'].find do |s|
697+
s.is_a?(EventSubscriber)
698+
end
699+
end
700+
701+
before do
702+
Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
703+
Person.collection.create
704+
Account.collection.create
705+
Mongoid::Clients.with_name(:default).subscribe(Mongo::Monitoring::COMMAND, EventSubscriber.new)
706+
subscriber.clear_events!
707+
end
708+
709+
after do
710+
Mongoid::Clients.with_name(:default).database.collections.each(&:drop)
711+
end
712+
713+
context 'when transactions are supported' do
714+
require_transaction_support
715+
716+
context 'when no error raised' do
717+
before do
718+
Mongoid.transaction do
719+
Person.create!
720+
end
721+
end
722+
723+
it 'commits the transacrion' do
724+
expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(0)
725+
expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(1)
726+
end
727+
728+
it 'executes the commands inside the transaction' do
729+
expect(Person.count).to be(1)
730+
end
731+
end
732+
733+
context 'When an error raised' do
734+
let!(:error) do
735+
capture_exception do
736+
Mongoid.transaction do
737+
Person.create!
738+
Account.create!
739+
end
740+
end
741+
end
742+
743+
it 'aborts the transaction' do
744+
expect(other_events.count { |e| e.command_name == 'abortTransaction'}).to be(1)
745+
expect(other_events.count { |e| e.command_name == 'commitTransaction'}).to be(0)
746+
end
747+
748+
it 'passes on the error' do
749+
expect(error).to be_a(Mongoid::Errors::Validations)
750+
end
751+
752+
it 'reverts changes' do
753+
expect(Account.count).to be(0)
754+
expect(Person.count).to be(0)
755+
end
756+
end
757+
end
758+
end
738759
end

0 commit comments

Comments
 (0)