1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2009 Oracle.  All rights reserved.
5 *
6 */
7using System;
8using System.Collections.Generic;
9using System.Text;
10using BerkeleyDB.Internal;
11
12namespace BerkeleyDB {
13    /// <summary>
14    /// A class representing configuration parameters for a
15    /// <see cref="Transaction"/>.
16    /// </summary>
17    public class TransactionConfig {
18        /// <summary>
19        /// Specifies the log flushing behavior on transaction commit
20        /// </summary>
21        public enum LogFlush {
22            /// <summary>
23            /// Use Berkeley DB's default behavior of syncing the log on commit.
24            /// </summary>
25            DEFAULT,
26            /// <summary>
27            /// Berkeley DB will not write or synchronously flush the log on
28            /// transaction commit or prepare.
29            /// </summary>
30            /// <remarks>
31            /// <para>
32            /// This means the transaction will exhibit the ACI (atomicity,
33            /// consistency, and isolation) properties, but not D (durability);
34            /// that is, database integrity will be maintained but it is
35            /// possible that this transaction may be undone during recovery.
36            /// </para>
37            /// </remarks>
38            NOSYNC,
39            /// <summary>
40            /// Berkeley DB will write, but will not synchronously flush, the
41            /// log on transaction commit or prepare.
42            /// </summary>
43            /// <remarks>
44            /// <para>
45            /// This means that transactions exhibit the ACI (atomicity,
46            /// consistency, and isolation) properties, but not D (durability);
47            /// that is, database integrity will be maintained, but if the
48            /// system fails, it is possible some number of the most recently
49            /// committed transactions may be undone during recovery. The number
50            /// of transactions at risk is governed by how often the system
51            /// flushes dirty buffers to disk and how often the log is
52            /// checkpointed.
53            /// </para>
54            /// <para>
55            /// For consistent behavior across the environment, all
56            /// <see cref="DatabaseEnvironment"/> objects opened in the
57            /// environment must either set WRITE_NOSYNC, or the
58            /// DB_TXN_WRITE_NOSYNC flag should be specified in the DB_CONFIG
59            /// configuration file.
60            /// </para>
61            /// </remarks>
62            WRITE_NOSYNC,
63            /// <summary>
64            /// Berkeley DB will synchronously flush the log on transaction
65            /// commit or prepare.
66            /// </summary>
67            /// <remarks>
68            /// This means the transaction will exhibit all of the ACID
69            /// (atomicity, consistency, isolation, and durability) properties.
70            /// </remarks>
71            SYNC
72        };
73        /// <summary>
74        /// The degree of isolation for this transaction
75        /// </summary>
76        public Isolation IsolationDegree;
77        /// <summary>
78        /// If true and a lock is unavailable for any Berkeley DB operation
79        /// performed in the context of a transaction, cause the operation to
80        /// throw a <see cref="DeadlockException"/>
81        /// (or <see cref="LockNotGrantedException"/> if configured with
82        /// <see cref="DatabaseEnvironmentConfig.TimeNotGranted"/>).
83        /// </summary>
84        /// <remarks>
85        /// <para>
86        /// This setting overrides the behavior specified by
87        /// <see cref="DatabaseEnvironmentConfig.TxnNoWait"/>.
88        /// </para>
89        /// </remarks>
90        public bool NoWait;
91        /// <summary>
92        /// If true, this transaction will execute with snapshot isolation.
93        /// </summary>
94        /// <remarks>
95        /// <para>
96        /// For databases with <see cref="DatabaseConfig.UseMVCC"/> set, data
97        /// values will be read as they are when the transaction begins, without
98        /// taking read locks. Silently ignored for operations on databases with
99        /// <see cref="DatabaseConfig.UseMVCC"/> not set on the underlying
100        /// database (read locks are acquired).
101        /// </para>
102        /// <para>
103        /// A <see cref="DeadlockException"/> will be thrown from update
104        /// operations if a snapshot transaction attempts to update data which
105        /// was modified after the snapshot transaction read it.
106        /// </para>
107        /// </remarks>
108        public bool Snapshot;
109        /// <summary>
110        /// Log sync behavior on transaction commit or prepare.
111        /// </summary>
112        /// <remarks>
113        /// <para>
114        /// This setting overrides the behavior specified by
115        /// <see cref="DatabaseEnvironmentConfig.TxnNoSync"/> and
116        /// <see cref="DatabaseEnvironmentConfig.TxnWriteNoSync"/>.
117        /// </para>
118        /// </remarks>
119        public LogFlush SyncAction;
120
121        internal uint flags {
122            get {
123                uint ret = 0;
124
125                switch (IsolationDegree) {
126                    case (Isolation.DEGREE_ONE):
127                        ret |= DbConstants.DB_READ_UNCOMMITTED;
128                        break;
129                    case (Isolation.DEGREE_TWO):
130                        ret |= DbConstants.DB_READ_COMMITTED;
131                        break;
132                }
133
134                ret |= NoWait ? DbConstants.DB_TXN_NOWAIT : 0;
135                ret |= Snapshot ? DbConstants.DB_TXN_SNAPSHOT : 0;
136
137                switch (SyncAction) {
138                    case (LogFlush.NOSYNC):
139                        ret |= DbConstants.DB_TXN_NOSYNC;
140                        break;
141                    case (LogFlush.SYNC):
142                        ret |= DbConstants.DB_TXN_SYNC;
143                        break;
144                    case (LogFlush.WRITE_NOSYNC):
145                        ret |= DbConstants.DB_TXN_WRITE_NOSYNC;
146                        break;
147                }
148
149                return ret;
150            }
151        }
152
153        private uint _lckTimeout;
154        internal bool lockTimeoutIsSet;
155        /// <summary>
156        /// The timeout value for locks for the transaction.
157        /// </summary>
158        /// <remarks>
159        /// <para>
160        /// Timeouts are checked whenever a thread of control blocks on a lock
161        /// or when deadlock detection is performed. This timeout is for any
162        /// single lock request. As timeouts are only checked when the lock
163        /// request first blocks or when deadlock detection is performed, the
164        /// accuracy of the timeout depends on how often deadlock detection is
165        /// performed.
166        /// </para>
167        /// <para>
168        /// Timeout values may be specified for the database environment as a
169        /// whole. See <see cref="DatabaseEnvironmentConfig.LockTimeout"/> for
170        /// more information.
171        /// </para>
172        /// </remarks>
173        public uint LockTimeout {
174            get { return _lckTimeout; }
175            set {
176                lockTimeoutIsSet = true;
177                _lckTimeout = value;
178            }
179        }
180
181        private string _name;
182        internal bool nameIsSet;
183        /// <summary>
184        /// The transaction's name. The name is returned by
185        /// <see cref="DatabaseEnvironment.TransactionSystemStats"/>
186        /// and displayed by
187        /// <see cref="DatabaseEnvironment.PrintTransactionSystemStats"/>.
188        /// </summary>
189        /// <remarks>
190        /// If the database environment has been configured for logging and the
191        /// Berkeley DB library was built in Debug mode (or with DIAGNOSTIC
192        /// defined), a debugging log record is written including the
193        /// transaction ID and the name.
194        /// </remarks>
195        public string Name {
196            get { return _name; }
197            set {
198                nameIsSet = (value != null);
199                _name = value;
200            }
201        }
202
203        private uint _txnTimeout;
204        internal bool txnTimeoutIsSet;
205        /// <summary>
206        /// The timeout value for locks for the transaction.
207        /// </summary>
208        /// <remarks>
209        /// <para>
210        /// Timeouts are checked whenever a thread of control blocks on a lock
211        /// or when deadlock detection is performed. This timeout is for the
212        /// life of the transaction. As timeouts are only checked when the lock
213        /// request first blocks or when deadlock detection is performed, the
214        /// accuracy of the timeout depends on how often deadlock detection is
215        /// performed.
216        /// </para>
217        /// <para>
218        /// Timeout values may be specified for the database environment as a
219        /// whole. See <see cref="DatabaseEnvironmentConfig.TxnTimeout"/> for
220        /// more information.
221        /// </para>
222        /// </remarks>
223        public uint TxnTimeout {
224            get { return _txnTimeout; }
225            set {
226                txnTimeoutIsSet = true;
227                _txnTimeout = value;
228            }
229        }
230
231        /// <summary>
232        /// Instantiate a new TransactionConfig object
233        /// </summary>
234        public TransactionConfig() {
235            IsolationDegree = Isolation.DEGREE_THREE;
236            SyncAction = LogFlush.DEFAULT;
237        }
238    }
239}