forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAdoNetTransactionFactory.cs
123 lines (110 loc) · 3.13 KB
/
AdoNetTransactionFactory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using NHibernate.Dialect;
using NHibernate.Engine;
using NHibernate.Engine.Transaction;
using NHibernate.Exceptions;
namespace NHibernate.Transaction
{
/// <summary>
/// Minimal <see cref="ITransaction"/> factory implementation.
/// Does not support system <see cref="System.Transactions.Transaction"/>.
/// </summary>
public partial class AdoNetTransactionFactory : ITransactionFactory
{
private static readonly INHibernateLogger _isolatorLog = NHibernateLogger.For(typeof(ITransactionFactory));
/// <inheritdoc />
public virtual ITransaction CreateTransaction(ISessionImplementor session)
{
return new AdoTransaction(session);
}
/// <inheritdoc />
public virtual void EnlistInSystemTransactionIfNeeded(ISessionImplementor session)
{
// nothing need to do here, we only support local transactions with this factory
}
/// <inheritdoc />
public virtual void ExplicitJoinSystemTransaction(ISessionImplementor session)
{
throw new NotSupportedException("The current transaction factory does not support system transactions.");
}
/// <inheritdoc />
public virtual bool IsInActiveSystemTransaction(ISessionImplementor session)
{
return false;
}
/// <inheritdoc />
public virtual void ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork work, bool transacted)
{
if (session == null)
throw new ArgumentNullException(nameof(session));
if (work == null)
throw new ArgumentNullException(nameof(work));
DbConnection connection = null;
DbTransaction trans = null;
try
{
// We make an exception for SQLite and use the session's connection,
// since SQLite only allows one connection to the database.
connection = session.Factory.Dialect is SQLiteDialect
? session.Connection
: session.ConnectionManager.GetNewConnection();
if (transacted)
{
trans = connection.BeginTransaction();
}
work.DoWork(connection, trans);
if (transacted)
{
trans.Commit();
}
}
catch (Exception t)
{
using (session.BeginContext())
{
try
{
if (trans != null && connection.State != ConnectionState.Closed)
{
trans.Rollback();
}
}
catch (Exception ignore)
{
_isolatorLog.Debug(ignore, "Unable to rollback transaction");
}
switch (t)
{
case HibernateException _:
throw;
case DbException _:
throw ADOExceptionHelper.Convert(session.Factory.SQLExceptionConverter, t,
"error performing isolated work");
default:
throw new HibernateException("error performing isolated work", t);
}
}
}
finally
{
try
{
trans?.Dispose();
}
catch (Exception ignore)
{
_isolatorLog.Warn(ignore, "Unable to dispose transaction");
}
if (connection != null && session.Factory.Dialect is SQLiteDialect == false)
session.Factory.ConnectionProvider.CloseConnection(connection);
}
}
/// <inheritdoc />
public virtual void Configure(IDictionary<string, string> props)
{
}
}
}