11
11
using System ;
12
12
using System . Data ;
13
13
using System . Data . Common ;
14
-
15
14
using NHibernate . Engine ;
16
15
using NHibernate . Exceptions ;
17
16
using NHibernate . Impl ;
@@ -26,51 +25,34 @@ public partial class DbTimestampType : AbstractDateTimeType
26
25
{
27
26
28
27
/// <inheritdoc />
29
- public override Task < object > SeedAsync ( ISessionImplementor session , CancellationToken cancellationToken )
28
+ public override async Task < object > SeedAsync ( ISessionImplementor session , CancellationToken cancellationToken )
30
29
{
31
- if ( cancellationToken . IsCancellationRequested )
32
- {
33
- return Task . FromCanceled < object > ( cancellationToken ) ;
34
- }
35
- try
30
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
31
+ if ( session == null )
36
32
{
37
- if ( session == null )
38
- {
39
- log . Debug ( "incoming session was null; using current application host time" ) ;
40
- return base . SeedAsync ( null , cancellationToken ) ;
41
- }
42
- if ( ! session . Factory . Dialect . SupportsCurrentTimestampSelection )
43
- {
44
- log . Info ( "falling back to application host based timestamp, as dialect does not support current timestamp selection" ) ;
45
- return base . SeedAsync ( session , cancellationToken ) ;
46
- }
47
- return GetCurrentTimestampAsync ( session , cancellationToken ) ;
33
+ log . Debug ( "incoming session was null; using current application host time" ) ;
34
+ return await ( base . SeedAsync ( null , cancellationToken ) ) . ConfigureAwait ( false ) ;
48
35
}
49
- catch ( Exception ex )
36
+ if ( ! session . Factory . Dialect . SupportsCurrentTimestampSelection )
50
37
{
51
- return Task . FromException < object > ( ex ) ;
38
+ log . Info ( "falling back to application host based timestamp, as dialect does not support current timestamp selection" ) ;
39
+ return await ( base . SeedAsync ( session , cancellationToken ) ) . ConfigureAwait ( false ) ;
52
40
}
41
+ return await ( GetCurrentTimestampAsync ( session , cancellationToken ) ) . ConfigureAwait ( false ) ;
53
42
}
54
43
55
- private Task < object > GetCurrentTimestampAsync ( ISessionImplementor session , CancellationToken cancellationToken )
44
+ protected virtual async Task < DateTime > GetCurrentTimestampAsync ( ISessionImplementor session , CancellationToken cancellationToken )
56
45
{
57
- if ( cancellationToken . IsCancellationRequested )
58
- {
59
- return Task . FromCanceled < object > ( cancellationToken ) ;
60
- }
61
- try
62
- {
63
- Dialect . Dialect dialect = session . Factory . Dialect ;
64
- string timestampSelectString = dialect . CurrentTimestampSelectString ;
65
- return UsePreparedStatementAsync ( timestampSelectString , session , cancellationToken ) ;
66
- }
67
- catch ( Exception ex )
68
- {
69
- return Task . FromException < object > ( ex ) ;
70
- }
46
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
47
+ var dialect = session . Factory . Dialect ;
48
+ // Need to round notably for Sql Server DateTime with Odbc, which has a 3.33ms resolution,
49
+ // causing stale data update failure 2/3 of times if not rounded to 10ms.
50
+ return Round (
51
+ await ( UsePreparedStatementAsync ( dialect . CurrentTimestampSelectString , session , cancellationToken ) ) . ConfigureAwait ( false ) ,
52
+ dialect . TimestampResolutionInTicks ) ;
71
53
}
72
54
73
- protected virtual async Task < object > UsePreparedStatementAsync ( string timestampSelectString , ISessionImplementor session , CancellationToken cancellationToken )
55
+ protected virtual async Task < DateTime > UsePreparedStatementAsync ( string timestampSelectString , ISessionImplementor session , CancellationToken cancellationToken )
74
56
{
75
57
cancellationToken . ThrowIfCancellationRequested ( ) ;
76
58
var tsSelect = new SqlString ( timestampSelectString ) ;
0 commit comments