Skip to content

Commit f17d3fc

Browse files
committed
Example for nhibernate#1452
1 parent b6f16b6 commit f17d3fc

11 files changed

+159
-85
lines changed

src/AsyncGenerator.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@
9696
- conversion: Ignore
9797
name: Exists
9898
containingTypeName: AbstractCollectionPersister
99+
- conversion: ToAsync
100+
rule: TransactionCompletion
99101
- conversion: ToAsync
100102
name: ExecuteReader
101103
containingTypeName: IBatcher
@@ -131,6 +133,7 @@
131133
requiresCancellationToken:
132134
- rule: EventListener
133135
- rule: ICache
136+
- rule: TransactionCompletion
134137
scanMethodBody: true
135138
scanForMissingAsyncMembers:
136139
- all: true
@@ -253,6 +256,14 @@ methodRules:
253256
- containingType: NHibernate.Cache.ICache
254257
name: Unlock
255258
name: ICache
259+
- filters:
260+
- containingType: NHibernate.Action.IAfterTransactionCompletionProcess
261+
name: AfterTransactionCompletion
262+
- containingType: NHibernate.Action.IBeforeTransactionCompletionProcess
263+
name: BeforeTransactionCompletion
264+
- containingType: NHibernate.Action.EntityAction
265+
name: BeforeTransactionCompletionProcessImpl
266+
name: TransactionCompletion
256267
- filters:
257268
- containingNamespace: NHibernate
258269
- containingType: NHibernate.Tool.hbm2ddl.SchemaUpdate
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace NHibernate.Action
6+
{
7+
public class AfterTransactionCompletionProcess : IAfterTransactionCompletionProcess
8+
{
9+
private readonly Action<bool> _syncAction;
10+
private readonly Func<bool, CancellationToken, Task> _asyncAction;
11+
12+
public AfterTransactionCompletionProcess(Action<bool> syncAction, Func<bool, CancellationToken, Task> asyncAction)
13+
{
14+
_syncAction = syncAction;
15+
_asyncAction = asyncAction;
16+
}
17+
18+
public void AfterTransactionCompletion(bool success)
19+
{
20+
_syncAction(success);
21+
}
22+
23+
public Task AfterTransactionCompletionAsync(bool success, CancellationToken cancellationToken)
24+
{
25+
return _asyncAction(success, cancellationToken);
26+
}
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace NHibernate.Action
6+
{
7+
public class BeforeTransactionCompletionProcess : IBeforeTransactionCompletionProcess
8+
{
9+
private readonly System.Action _syncAction;
10+
private readonly Func<CancellationToken, Task> _asyncAction;
11+
12+
public BeforeTransactionCompletionProcess(System.Action syncAction, Func<CancellationToken, Task> asyncAction)
13+
{
14+
_syncAction = syncAction;
15+
_asyncAction = asyncAction;
16+
}
17+
18+
public void BeforeTransactionCompletion()
19+
{
20+
_syncAction();
21+
}
22+
23+
public Task BeforeTransactionCompletionAsync(CancellationToken cancellationToken)
24+
{
25+
return _asyncAction(cancellationToken);
26+
}
27+
}
28+
}

src/NHibernate/Action/BulkOperationCleanupAction.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,28 @@ public void Execute()
111111
// nothing to do
112112
}
113113

114-
public BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
114+
public IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
115115
{
116-
get
117-
{
116+
get
117+
{
118118
return null;
119119
}
120120
}
121121

122-
public AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
122+
public IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
123123
{
124124
get
125125
{
126-
return new AfterTransactionCompletionProcessDelegate((success) =>
127-
{
128-
this.EvictEntityRegions();
129-
this.EvictCollectionRegions();
130-
});
126+
return new AfterTransactionCompletionProcess(AfterTransactionCompletion, AfterTransactionCompletionAsync);
131127
}
132128
}
133129

130+
private void AfterTransactionCompletion(bool success)
131+
{
132+
EvictEntityRegions();
133+
EvictCollectionRegions();
134+
}
135+
134136
private void EvictCollectionRegions()
135137
{
136138
if (affectedCollectionRoles != null)

src/NHibernate/Action/CollectionAction.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,31 +104,33 @@ public virtual void BeforeExecutions()
104104
/// <summary>Execute this action</summary>
105105
public abstract void Execute();
106106

107-
public virtual BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
107+
public virtual IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
108108
{
109109
get
110110
{
111111
return null;
112112
}
113113
}
114114

115-
public virtual AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
115+
public virtual IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
116116
{
117117

118118
get
119119
{
120120
// Only make sense to add the delegate if there is a cache.
121121
if (persister.HasCache)
122122
{
123-
return new AfterTransactionCompletionProcessDelegate((success) =>
124-
{
125-
CacheKey ck = new CacheKey(key, persister.KeyType, persister.Role, Session.Factory);
126-
persister.Cache.Release(ck, softLock);
127-
});
123+
return new AfterTransactionCompletionProcess(AfterTransactionCompletion, AfterTransactionCompletionAsync);
128124
}
129125
return null;
130126
}
131127
}
128+
129+
private void AfterTransactionCompletion(bool success)
130+
{
131+
CacheKey ck = new CacheKey(key, persister.KeyType, persister.Role, Session.Factory);
132+
persister.Cache.Release(ck, softLock);
133+
}
132134

133135
#endregion
134136

src/NHibernate/Action/CollectionUpdateAction.cs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -113,49 +113,51 @@ private void PostUpdate()
113113
}
114114
}
115115

116-
public override BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
116+
public override IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
117117
{
118118
get
119119
{
120120
return null;
121121
}
122122
}
123123

124-
public override AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
124+
public override IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
125125
{
126126
get
127127
{
128128
// Only make sense to add the delegate if there is a cache.
129129
if (Persister.HasCache)
130130
{
131131
// NH Different behavior: to support unlocking collections from the cache.(r3260)
132-
return new AfterTransactionCompletionProcessDelegate((success) =>
133-
{
134-
CacheKey ck = Session.GenerateCacheKey(Key, Persister.KeyType, Persister.Role);
135-
136-
if (success)
137-
{
138-
// we can't disassemble a collection if it was uninitialized
139-
// or detached from the session
140-
if (Collection.WasInitialized && Session.PersistenceContext.ContainsCollection(Collection))
141-
{
142-
CollectionCacheEntry entry = new CollectionCacheEntry(Collection, Persister);
143-
bool put = Persister.Cache.AfterUpdate(ck, entry, null, Lock);
144-
145-
if (put && Session.Factory.Statistics.IsStatisticsEnabled)
146-
{
147-
Session.Factory.StatisticsImplementor.SecondLevelCachePut(Persister.Cache.RegionName);
148-
}
149-
}
150-
}
151-
else
152-
{
153-
Persister.Cache.Release(ck, Lock);
154-
}
155-
});
132+
return new AfterTransactionCompletionProcess(AfterTransactionCompletion, AfterTransactionCompletionAsync);
156133
}
157134
return null;
158135
}
159136
}
137+
138+
private void AfterTransactionCompletion(bool success)
139+
{
140+
CacheKey ck = Session.GenerateCacheKey(Key, Persister.KeyType, Persister.Role);
141+
142+
if (success)
143+
{
144+
// we can't disassemble a collection if it was uninitialized
145+
// or detached from the session
146+
if (Collection.WasInitialized && Session.PersistenceContext.ContainsCollection(Collection))
147+
{
148+
CollectionCacheEntry entry = new CollectionCacheEntry(Collection, Persister);
149+
bool put = Persister.Cache.AfterUpdate(ck, entry, null, Lock);
150+
151+
if (put && Session.Factory.Statistics.IsStatisticsEnabled)
152+
{
153+
Session.Factory.StatisticsImplementor.SecondLevelCachePut(Persister.Cache.RegionName);
154+
}
155+
}
156+
}
157+
else
158+
{
159+
Persister.Cache.Release(ck, Lock);
160+
}
161+
}
160162
}
161-
}
163+
}

src/NHibernate/Action/EntityAction.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,22 @@ public void BeforeExecutions()
102102

103103
public abstract void Execute();
104104

105-
public virtual BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
105+
public virtual IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
106106
{
107107
get
108108
{
109109
return NeedsBeforeTransactionCompletion()
110-
? new BeforeTransactionCompletionProcessDelegate(BeforeTransactionCompletionProcessImpl)
110+
? new BeforeTransactionCompletionProcess(BeforeTransactionCompletionProcessImpl, BeforeTransactionCompletionProcessImplAsync)
111111
: null;
112112
}
113113
}
114114

115-
public virtual AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
115+
public virtual IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
116116
{
117117
get
118118
{
119119
return NeedsAfterTransactionCompletion()
120-
? new AfterTransactionCompletionProcessDelegate(AfterTransactionCompletionProcessImpl)
120+
? new AfterTransactionCompletionProcess(AfterTransactionCompletionProcessImpl, AfterTransactionCompletionProcessImplAsync)
121121
: null;
122122
}
123123
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
4+
namespace NHibernate.Action
5+
{
6+
public partial interface IAfterTransactionCompletionProcess
7+
{
8+
/// <summary>
9+
/// Perform whatever processing is encapsulated here after completion of the transaction.
10+
/// </summary>
11+
/// <param name="success">Did the transaction complete successfully? True means it did.</param>
12+
void AfterTransactionCompletion(bool success);
13+
}
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
4+
namespace NHibernate.Action
5+
{
6+
public partial interface IBeforeTransactionCompletionProcess
7+
{
8+
void BeforeTransactionCompletion();
9+
}
10+
}

src/NHibernate/Action/IExecutable.cs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
1-
using NHibernate.Engine;
2-
31
namespace NHibernate.Action
42
{
5-
/// <summary>
6-
/// Delegate representing some process that needs to occur before transaction completion.
7-
/// </summary>
8-
/// <remarks>
9-
/// NH specific: C# does not support dynamic interface proxies so a delegate is used in
10-
/// place of the Hibernate interface (see Action/BeforeTransactionCompletionProcess). The
11-
/// delegate omits the <see cref="ISessionImplementor" /> parameter as it is not used.
12-
/// </remarks>
13-
public delegate void BeforeTransactionCompletionProcessDelegate();
14-
15-
/// <summary>
16-
/// Delegate representing some process that needs to occur after transaction completion.
17-
/// </summary>
18-
/// <param name="success"> Did the transaction complete successfully? True means it did.</param>
19-
/// <remarks>
20-
/// NH specific: C# does not support dynamic interface proxies so a delegate is used in
21-
/// place of the Hibernate interface (see Action/AfterTransactionCompletionProcess). The
22-
/// delegate omits the <see cref="ISessionImplementor" /> parameter as it is not used.
23-
/// </remarks>
24-
public delegate void AfterTransactionCompletionProcessDelegate(bool success);
25-
263
/// <summary>
274
/// An operation which may be scheduled for later execution.
285
/// Usually, the operation is a database insert/update/delete,
@@ -44,11 +21,11 @@ public partial interface IExecutable
4421
/// <summary>
4522
/// Get the before-transaction-completion process, if any, for this action.
4623
/// </summary>
47-
BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess { get; }
48-
24+
IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess { get; }
25+
4926
/// <summary>
5027
/// Get the after-transaction-completion process, if any, for this action.
5128
/// </summary>
52-
AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess { get; }
29+
IAfterTransactionCompletionProcess AfterTransactionCompletionProcess { get; }
5330
}
5431
}

0 commit comments

Comments
 (0)