1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.ActiveRecord
.Tests
18 using NUnit
.Framework
;
20 using Castle
.ActiveRecord
.Tests
.Model
;
23 public class TransactionScopeTestCase
: AbstractActiveRecordTest
26 public void TransactionScopeUsage()
28 ISession session1
, session2
, session3
, session4
;
30 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
33 using(new TransactionScope())
35 session1
= Blog
.Holder
.CreateSession(typeof(Blog
));
36 session2
= Blog
.Holder
.CreateSession(typeof(Post
));
37 session3
= Blog
.Holder
.CreateSession(typeof(Blog
));
38 session4
= Blog
.Holder
.CreateSession(typeof(Post
));
40 Assert
.IsNotNull(session1
);
41 Assert
.IsNotNull(session2
);
42 Assert
.IsNotNull(session3
);
43 Assert
.IsNotNull(session3
);
45 Assert
.IsTrue(session2
== session1
);
46 Assert
.IsTrue(session3
== session1
);
47 Assert
.IsTrue(session4
== session1
);
52 session1
= Blog
.Holder
.CreateSession(typeof(Blog
));
53 session2
= Blog
.Holder
.CreateSession(typeof(Blog
));
55 Assert
.IsNotNull(session1
);
56 Assert
.IsNotNull(session2
);
57 Assert
.IsTrue(session1
!= session2
);
59 Blog
.Holder
.ReleaseSession(session1
);
60 Blog
.Holder
.ReleaseSession(session2
);
64 public void RollbackVote()
66 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
72 using(TransactionScope transaction
= new TransactionScope())
74 Blog blog
= new Blog();
75 blog
.Author
= "hammett";
76 blog
.Name
= "some name";
79 Post post
= new Post(blog
, "title", "post contents", "Castle");
82 // pretend something went wrong
84 transaction
.VoteRollBack();
87 Blog
[] blogs
= Blog
.FindAll();
88 Assert
.AreEqual(0, blogs
.Length
);
90 Post
[] posts
= Post
.FindAll();
91 Assert
.AreEqual(0, posts
.Length
);
95 public void RollbackOnDispose()
97 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
103 using(TransactionScope transaction
= new TransactionScope(OnDispose
.Rollback
))
105 Blog blog
= new Blog();
106 blog
.Author
= "hammett";
107 blog
.Name
= "some name";
110 Post post
= new Post(blog
, "title", "post contents", "Castle");
114 Blog
[] blogs
= Blog
.FindAll();
115 Assert
.AreEqual(0, blogs
.Length
);
117 Post
[] posts
= Post
.FindAll();
118 Assert
.AreEqual(0, posts
.Length
);
122 public void CommitVote()
124 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
130 using(TransactionScope transaction
= new TransactionScope())
132 Blog blog
= new Blog();
133 blog
.Author
= "hammett";
134 blog
.Name
= "some name";
137 Post post
= new Post(blog
, "title", "post contents", "Castle");
140 // Default to VoteCommit
143 Blog
[] blogs
= Blog
.FindAll();
144 Assert
.AreEqual(1, blogs
.Length
);
146 Post
[] posts
= Post
.FindAll();
147 Assert
.AreEqual(1, posts
.Length
);
151 public void RollbackUponException()
153 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
159 using(TransactionScope transaction
= new TransactionScope())
161 Blog blog
= new Blog();
162 blog
.Author
= "hammett";
163 blog
.Name
= "some name";
166 Post post
= new Post(blog
, "title", "post contents", "Castle");
170 post
.SaveWithException();
174 transaction
.VoteRollBack();
178 Blog
[] blogs
= Blog
.FindAll();
179 Assert
.AreEqual(0, blogs
.Length
);
181 Post
[] posts
= Post
.FindAll();
182 Assert
.AreEqual(0, posts
.Length
);
186 public void NestedTransactions()
188 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
194 using(TransactionScope root
= new TransactionScope())
196 Blog blog
= new Blog();
198 using(TransactionScope t1
= new TransactionScope(TransactionMode
.Inherits
))
200 blog
.Author
= "hammett";
201 blog
.Name
= "some name";
207 using(TransactionScope t2
= new TransactionScope(TransactionMode
.Inherits
))
209 Post post
= new Post(blog
, "title", "post contents", "Castle");
213 post
.SaveWithException();
222 Blog
[] blogs
= Blog
.FindAll();
223 Assert
.AreEqual(0, blogs
.Length
);
225 Post
[] posts
= Post
.FindAll();
226 Assert
.AreEqual(0, posts
.Length
);
230 public void LotsOfNestedTransactionWithDifferentConfigurations()
232 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
238 using(TransactionScope root
= new TransactionScope())
240 using(TransactionScope t1
= new TransactionScope()) // Isolated
242 Blog blog
= new Blog();
244 Blog
.FindAll(); // Just to force a session association
246 using(TransactionScope t1n
= new TransactionScope(TransactionMode
.Inherits
))
248 Blog
.FindAll(); // Just to force a session association
250 blog
.Author
= "hammett";
251 blog
.Name
= "some name";
255 using(TransactionScope t1n
= new TransactionScope(TransactionMode
.Inherits
))
257 Post post
= new Post(blog
, "title", "post contents", "Castle");
265 Blog
.FindAll(); // Cant be locked
267 using(TransactionScope t2
= new TransactionScope())
269 Blog blog
= new Blog();
270 Blog
.FindAll(); // Just to force a session association
272 using(new TransactionScope())
274 Blog
.FindAll(); // Just to force a session association
276 blog
.Author
= "hammett";
277 blog
.Name
= "some name";
281 using(TransactionScope t1n
= new TransactionScope(TransactionMode
.Inherits
))
283 Post post
= new Post(blog
, "title", "post contents", "Castle");
287 post
.SaveWithException();
299 Blog
[] blogs
= Blog
.FindAll();
300 Assert
.AreEqual(1, blogs
.Length
);
302 Post
[] posts
= Post
.FindAll();
303 Assert
.AreEqual(0, posts
.Length
);
307 public void MixingSessionScopeAndTransactionScopes()
309 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
315 using(new SessionScope())
317 using(TransactionScope root
= new TransactionScope())
319 using(TransactionScope t1
= new TransactionScope()) // Isolated
321 Blog blog
= new Blog();
323 Blog
.FindAll(); // Just to force a session association
325 using(new TransactionScope(TransactionMode
.Inherits
))
327 Blog
.FindAll(); // Just to force a session association
329 blog
.Author
= "hammett";
330 blog
.Name
= "some name";
334 using(new TransactionScope(TransactionMode
.Inherits
))
336 Post post
= new Post(blog
, "title", "post contents", "Castle");
344 Blog
.FindAll(); // Cant be locked
346 using(new TransactionScope())
348 Blog blog
= new Blog();
349 Blog
.FindAll(); // Just to force a session association
351 using(new TransactionScope())
353 Blog
.FindAll(); // Just to force a session association
355 blog
.Author
= "hammett";
356 blog
.Name
= "some name";
360 using(TransactionScope t1n
= new TransactionScope(TransactionMode
.Inherits
))
362 Post post
= new Post(blog
, "title", "post contents", "Castle");
366 post
.SaveWithException();
379 Blog
[] blogs
= Blog
.FindAll();
380 Assert
.AreEqual(1, blogs
.Length
);
382 Post
[] posts
= Post
.FindAll();
383 Assert
.AreEqual(0, posts
.Length
);
387 public void MixingSessionScopeAndTransactionScopes2()
389 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(PostLazy
), typeof(BlogLazy
));
392 PostLazy
.DeleteAll();
393 BlogLazy
.DeleteAll();
395 BlogLazy b
= new BlogLazy();
397 using(new SessionScope())
403 using(new TransactionScope())
405 for(int i
= 1; i
<= 10; i
++)
407 PostLazy post
= new PostLazy(b
, "t", "c", "General");
413 using(new SessionScope())
415 // We should load this outside the transaction scope
417 b
= BlogLazy
.Find(b
.Id
);
419 using(new TransactionScope())
421 int total
= b
.Posts
.Count
;
423 foreach(PostLazy p
in b
.Posts
)
432 BlogLazy
[] blogs
= BlogLazy
.FindAll();
433 Assert
.AreEqual(0, blogs
.Length
);
435 PostLazy
[] posts
= PostLazy
.FindAll();
436 Assert
.AreEqual(0, posts
.Length
);
440 public void MixingSessionScopeAndTransactionScopes3()
442 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(PostLazy
), typeof(BlogLazy
));
445 PostLazy
.DeleteAll();
446 BlogLazy
.DeleteAll();
448 BlogLazy b
= new BlogLazy();
450 using(new SessionScope())
456 using(new TransactionScope())
458 for(int i
= 1; i
<= 10; i
++)
460 PostLazy post
= new PostLazy(b
, "t", "c", "General");
466 using(new SessionScope())
468 // We should load this outside the transaction scope
470 b
= BlogLazy
.Find(b
.Id
);
472 using(TransactionScope transaction
= new TransactionScope())
474 int total
= b
.Posts
.Count
;
476 foreach(PostLazy p
in b
.Posts
)
483 transaction
.VoteRollBack();
487 BlogLazy
[] blogs
= BlogLazy
.FindAll();
488 Assert
.AreEqual(1, blogs
.Length
);
490 PostLazy
[] posts
= PostLazy
.FindAll();
491 Assert
.AreEqual(10, posts
.Length
);
495 public void MixingSessionScopeAndTransactionScopes4()
497 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
511 post
= new Post(b
, "t", "c", "General");
515 using(new SessionScope())
517 using(new TransactionScope(TransactionMode
.Inherits
))
525 Post post2
= Post
.Find(post
.Id
);
529 using(new TransactionScope(TransactionMode
.Inherits
))
531 Post post2
= Post
.Find(post
.Id
);
536 Blog
[] blogs
= Blog
.FindAll();
537 Assert
.AreEqual(1, blogs
.Length
);
539 Post
[] posts
= Post
.FindAll();
540 Assert
.AreEqual(1, posts
.Length
);
544 public void NestedTransactionWithRollbackOnDispose()
546 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Post
), typeof(Blog
));
552 using(new TransactionScope())
554 Blog blog
= new Blog();
556 using(TransactionScope t1
= new TransactionScope(TransactionMode
.Inherits
, OnDispose
.Rollback
))
558 blog
.Author
= "hammett";
559 blog
.Name
= "some name";
565 using(TransactionScope t2
= new TransactionScope(TransactionMode
.Inherits
, OnDispose
.Rollback
))
567 Post post
= new Post(blog
, "title", "post contents", "Castle");
571 post
.SaveWithException();
573 t2
.VoteCommit(); // Will never be called
577 // t2.VoteRollBack();
582 Blog
[] blogs
= Blog
.FindAll();
583 Assert
.AreEqual(0, blogs
.Length
);
585 Post
[] posts
= Post
.FindAll();
586 Assert
.AreEqual(0, posts
.Length
);
590 public void ReportedProblemOnForum()
592 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Company
), typeof(Person
));
595 using(new TransactionScope())
597 Company comp1
= new Company("comp1");
600 Company comp2
= new Company("comp2");
606 public void ExplicitFlushInsideSecondTransactionProblem()
608 ActiveRecordStarter
.Initialize(GetConfigSource(), typeof(Company
), typeof(Person
));
611 Company comp1
= new Company("comp1");
612 Company comp2
= new Company("comp2");
613 using(new SessionScope())
619 using(new SessionScope(FlushAction
.Never
))
621 using(TransactionScope tx
= new TransactionScope(OnDispose
.Rollback
))
623 Company comp2a
= Company
.Find(comp2
.Id
);
624 comp2a
.Name
= "changed";
628 using(new TransactionScope(OnDispose
.Rollback
))
630 Company
[] changedCompanies
= ActiveRecordMediator
<Company
>.FindAllByProperty("Name", "changed");
631 Assert
.AreEqual(1, changedCompanies
.Length
);
632 Company e2a
= changedCompanies
[0];
635 SessionScope
.Current
.Flush();
637 Assert
.AreEqual(0, ActiveRecordMediator
<Company
>.FindAllByProperty("Name", "changed").Length
);