Database Reference
In-Depth Information
name was too long for the SqlParameter object (hence it threw a “Value Would Be Truncated”
exception).
The library handles exceptions through the AggregateException class provided by the TPL; this class
holds a collection of exceptions. This is necessary because the library executes database calls in parallel.
As a result, more than one exception may be taking place at the same time. You need to aggregate these
exceptions and return them to the client for further processing.
For example, the shard library's ExecuteSingleNonQuery method takes a
ConcurrentQueue<Exception> parameter, which represents an object that stores exceptions. This object is
thread-safe, meaning that all running threads can add new exceptions to it safely without running into
concurrency issues. The following code shows that if an exception is detected in the
ExecuteSingleNonQuery method, the code adds the exception to the queue on line 14. Also, as a
convention, the exception is rethrown if the queue isn't provided (line 16):
1)
private static long ExecuteSingleNonQuery(
2)
SqlCommand command,
3)
SqlConnection connectionToUse,
4) System.Collections.Concurrent.ConcurrentQueue<Exception> exceptions
5) )
6) {
7) try
8) {
9) // ...
10) }
11) catch (Exception ex)
12) {
13)
if (exceptions != null)
14)
exceptions.Enqueue(ex);
15)
else
16)
throw;
17) }
18) }
The following code shows the ExecuteShardNonQuery method, which calls the
ExecuteSingleNonQuery method just described. Line 1 creates the exception queue ( ConcurrentQueue ),
which is passed as a variable to ExecuteSingleNonQuery . After the parallel execution of the database calls
is complete, the code checks whether the exception queue is empty. If it isn't empty, an
AggregateException is thrown, which contains the collection of exceptions stored in the exception queue
(lines 13 and 14):
1)
var exceptions = new System.Collections.Concurrent.ConcurrentQueue<Exception>();
2)
3)
Parallel.ForEach(connections, delegate(SqlConnection c)
4)
{
5)
long rowsAffected = ExecuteSingleNonQuery(command, c, exceptions);
6)
7)
lock (alock)
8)
res += rowsAffected;
9)
10) }
11) );
12)
13) if (!exceptions.IsEmpty)
14) throw new AggregateException(exceptions);
Search WWH ::




Custom Search