|
| 1 | +--- |
| 2 | +lastmod: 2018-09-29 |
| 3 | +date: 2018-09-29 |
| 4 | +title: Connection Reuse |
| 5 | +weight: 10 |
| 6 | +menu: |
| 7 | + main: |
| 8 | + parent: troubleshooting |
| 9 | +--- |
| 10 | + |
| 11 | +# Connection Reuse |
| 12 | + |
| 13 | +A `MySqlConnection` object may only be used for one operation at a time. It may not be shared |
| 14 | +across multiple threads and used simultaneously, nor reused on the same thread while there is |
| 15 | +an open `MySqlDataReader`. |
| 16 | + |
| 17 | +## Examples of Prohibited Use |
| 18 | + |
| 19 | +### Multiple Threads |
| 20 | + |
| 21 | +You may not execute multiple operations in parallel, for example: |
| 22 | + |
| 23 | +```csharp |
| 24 | +using (var connection = new MySqlConnection("...")) |
| 25 | +{ |
| 26 | + await connection.OpenAsync(); |
| 27 | + await Task.WhenAll( // don't do this |
| 28 | + connection.ExecuteAsync("SELECT 1;"), |
| 29 | + connection.ExecuteAsync("SELECT 2;"), |
| 30 | + connection.ExecuteAsync("SELECT 3;")); |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +### Nested Access on Single Thread |
| 35 | + |
| 36 | +You may not reuse the connection when there is an open `MySqlDataReader:` |
| 37 | + |
| 38 | +```csharp |
| 39 | +using (var connection = CreateOpenConnection()) |
| 40 | +using (var command = new MySqlCommand("SELECT id FROM ...", connection)) |
| 41 | +using (var reader = command.ExecuteReader()) |
| 42 | +{ |
| 43 | + while (reader.Read()) |
| 44 | + { |
| 45 | + var idToUpdate = reader.GetValue(0); |
| 46 | + connection.Execute("UPDATE ... SET ..."); // don't do this |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +## How to Fix |
| 52 | + |
| 53 | +For the multithreaded scenario, if concurrent access to the database is truly necessary, |
| 54 | +create and open a new `MySqlConnection` on each thread. But in most cases, you should |
| 55 | +just write code that sequentially `await`s each asychronous operation (without performing |
| 56 | +them in parallel). |
| 57 | + |
| 58 | + |
| 59 | +For the nested access, read all the values from the `MySqlDataReader` into memory, close |
| 60 | +the reader, then process the values. (If the data set is large, you may need to use a batching |
| 61 | +approach where you read a limited number of rows in each batch.) |
0 commit comments