2016-06-26 5 views
0

Я пишу программу, используя визуальную базовую базу данных 2015 и MySql, и я задал этот вопрос где-то в другом месте, но они не могли мне помочь.Два пользователя пытаются сделать то же самое в одно и то же время

К примеру у нас есть таблица с именем «пользователи»:

username | coins 
user1  |  3 
user2  |  5 

Я хочу, чтобы изменить значение монеты и этот код работает отлично, но в этом коде: 1- я получаю значение столбца. 2- Я добавляю единицу к значению. 3- Я положил значение в столбце. Таким образом, проблема в том, что, если база данных находится в сети, и два разных компьютера запускают программу и пытаются изменить значение в одно и то же время? Например, один из них пытается предоставить user1 2 монеты, а другой пытается предоставить пользователю 1 4 монеты. Затем они нажимают на добавление монеты одновременно. Первый компьютер получает значение, и он равен 3. Второй компьютер получает значение, а это 3. Первый компьютер добавляет 2 монеты (3 + 2 = 5) и кладет 5 в столбец. Теперь второй компьютер добавьте 4 монеты (3 + 4 = 7) и поместите 7 в столбец. Итак, у нас есть 7 в нашей колонке, но у нас должно быть 9, потому что 3 + 2 + 4 = 9

Итак, вот вопрос: есть ли способ добавить значение непосредственно в столбец или есть другой способ решить эту проблему проблема?

MysqlConn = New MySqlConnection 
    MysqlConn.ConnectionString = "Server='" & TextBox_MYSQL_Host.Text & "';UserID='" & TextBox_MYSQL_Username.Text & "';Password='" & TextBox_MYSQL_Password.Text & "';Database='" & TextBox_MYSQL_Database.Text & "';Character Set=utf8" 

    Try 
     MysqlConn.Open() 
     DataAdptr = New MySqlDataAdapter 
     DataTable = New DataTable 
     MysqlComd = New MySqlCommand 
     With MysqlComd 
      .Connection = MysqlConn 
      .CommandText = "Select * FROM users WHERE username ='" & user1.text & "';" 
     End With 
     DataAdptr.SelectCommand = MysqlComd 
     DataAdptr.Fill(DataTable) 
     If DataTable.Rows.Count = 0 Then 
      ' Error! 
     Else 
      Dim gold As Integer = DataTable.Rows(0).Item("coins").ToString() 
      gold = gold + 1 
      MysqlComd = New MySqlCommand 
      MysqlComd.Connection = MysqlConn 
      MysqlComd.CommandText = "UPDATE users SET coins='" & gold & "' WHERE username='" & user1.Text & "'" 
      MysqlComd.ExecuteNonQuery() 
     End If 
     MysqlConn.Close() 
    Catch ex As MySqlException 
     ' Connection Error 
    Finally 
     MysqlConn.Dispose() 
    End Try 
End Sub 
+1

использовать привязку параметров, добавить со значением и использовать блокировки строк. Вы добавляете SQL-инъекцию к своей проблеме с вышеупомянутой бессмысленной бессмыслицей. – Drew

+0

... конверсии типов, а также SQL-инъекции и общий хаос: попробуйте код с пользователем с именем 'D'Artagnan' – Plutonix

+0

Я новичок в программировании, и я понятия не имею, о чем вы говорите. Так что, пожалуйста, дайте код? Я могу поработать над этим и узнать что-то. – Armin

ответ

1

Игнорирование проблемы с вашим кодом, как указано в комментариях, есть два пути решения проблемы вы специально с просьбой о.

Во-первых, вы можете продолжать делать это так, как есть, и использовать оптимистичный параллелизм. То, что это делает, предполагает, что каждый пользователь является единственным пользователем, редактирующим данные и сохраняющим, как будто это так, и затем генерирует исключение, если оно окажется не таким. В частности, когда запись сохраняется, текущие значения в базе данных сравниваются с исходными данными, полученными этим пользователем, и новые значения будут сохранены тогда и только тогда, когда они совпадают. Если они этого не сделают, вам придется поймать ConcurrencyException, который будет выброшен и сделает все, что уместно. Обычно это будет получение данных снова и либо попросить пользователя снова начать редактирование, либо объединить текущие данные с их существующими изменениями.

Другой вариант - просто увеличить количество данных в базе данных, а не сохранять определенное значение, например.

UPDATE MyTable SET MyColumn = MyColumn + 1 WHERE ID = @ID 
Смежные вопросы