Новости
Документация
Download
Webboard
Поиск
FAQ/ЧаВо
Обратная связь




MySQL.RU - Webboard



Вернуться
MySQL + Transaction + C# (MarkT) 10/06/2010 - 14:43:45



From: MarkT - 10/06/2010 - 14:43:45
Subject:MySQL + Transaction + C#
-----------------
Здравствуйте. У меня проблема следующего характера:
Есть база MySQL - находиться на сервере, с ней работает программа написанная на C#.
Программа установлена на клиентские машины. Программа делает продажи товаров, предварительно отслеживая наличие конкретного товара на остатке.
Проблема в том что если одновременно продавать один и тот же товар, на разных клиентских машинах, то не работает механизм транзакций:
Пример:
- Остаток Тов1 на начало = 4 шт.
- Продажа с Клиента1 товара Тов1 в количестве 3шт. - Продажа с Клиента2 товара Тов1 в количестве 2шт.
- Остаток Тов1 на конец = -1шт.

Вот основные функции которые работают с транзакциями:
[code=csharp]using MySql.Data.MySqlClient;

public partial class Form1 : Form
{
MySqlConnection conn;//конект для БД
MySqlTransaction tr;//транзакция для БД

public Form1()
{
InitializeComponent();

if (conn != null)
{
conn.Dispose();
conn.Close();
conn = null;
}

string connStr = String.Format("server={0};user id={1}; password={2}; database=MyBase; pooling=false",
Start.HostOfDB, Start.UserOfDB, Start.PassOfDb);
try
{
conn = new MySqlConnection(connStr);
conn.Open();
}
catch (MySqlException ex)
{
MessageBox.Show("Ошибка подключения к серверу: " + ex.Message);
}
}

/// <summary>
/// делает запрос к БД и выдает ридер в котором находиться ответ на запрос
/// </summary>
/// <param name="TekstZap">текст запроса.</param>
public MySqlDataReader Zapros(string TekstZap)
{
MySqlDataReader Read = null;

MySqlCommand cmd = new MySqlCommand(TekstZap, conn, tr);

try
{
Read = cmd.ExecuteReader();
}
catch (MySqlException ex)
{
MessageBox.Show("Ошибка получения данных: " + ex.Message);
Read = null;
tr.Rollback();
}

return Read;
}

//делаем сохранение изменений для БД, команда <COMMIT> MySQL
public void Commit(int Rej)
{
if (Rej == 0)
{
if (tr != null)
{
tr.Dispose();
tr = null;
}
tr = conn.BeginTransaction(IsolationLevel.Serializable);
}
else if (Rej == 1)
{
tr.Commit();
tr.Dispose();
tr = null;
}
}

//***процедура при расчете чека и его подальшей оплаты***//
//---возвращает 1 - проведен
// 5 - товара нет на остатках
// 6 - Ошибка в запросе
private int Sell()
{
DateTime NachMes = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
DateTime TekDateTime = DateTime.Now;
MySqlDataReader MSQLR;
MySqlDataReader MSQLR2;
//---проверяем товар в ТЧ, тоесть есть ли остатки по даному товару---//
Commit(0);//---ВОТ ТУТ ВКЛЮЧАЕТСЯ ТРАНЗАКЦИЯ---//
if (Start.IsProvMinus == 0)//если нет разрешения проводить в минус
for (int q = 0; q < ZakazdataGrid.RowCount; ++q)
{
float KolvoReg = 0.0f;

//сначала получаем по регистру Остатки_движения
//а потом получаем по регистру Остатки
//дальше мы их складываем в список и обрабатываем
//если находим что есть меньше чем надо - сообщаем про ошибку
//---Остатки_Движение---//
MSQLR = Zapros("SELECT SUM(Kolvo) AS Kolvo, Flag, Date, Time, NomDocum, Document " +
"FROM ostatki_move " +
"WHERE ostatki_move.Tovar = " + ZakazdataGrid["KodTov", q].Value.ToString() + " AND " +
"ostatki_move.Date BETWEEN '" +
NachMes.ToString("yyyy-MM-dd") + "' AND '" +
TekDateTime.ToString("yyyy-MM-dd") + "' " +
"GROUP BY ostatki_move.Tovar, ostatki_move.Flag, ostatki_move.Date, ostatki_move.Time");
if (MSQLR == null)
return 6;
while (MSQLR.Read())
{
if (MSQLR.GetDateTime("Date").ToShortDateString() == TekDateTime.ToShortDateString())
if (CompareTime(MSQLR.GetString("Time"), TekDateTime.ToString("HH:mm:ss")) <= 1)
continue;

if (MSQLR.GetInt32("Flag") == 1)
KolvoReg = KolvoReg + MSQLR.GetFloat("Kolvo");
else
KolvoReg = KolvoReg - MSQLR.GetFloat("Kolvo");
}
MSQLR.Dispose();
MSQLR.Close();
MSQLR = null;

//---Остатки---//
MSQLR2 = Zapros("SELECT SUM(ostatki.Kolvo) AS Kolvo " +
"FROM ostatki " +
"WHERE ostatki.Tovar = " + ZakazdataGrid["KodTov", q].Value.ToString() + " AND " +
"ostatki.Date = '" + NachMes.ToString("yyyy-MM-dd") + "' " +
"GROUP BY ostatki.Tovar");
if (MSQLR2 == null)
return 6;
if (MSQLR2.Read())
{
KolvoReg = KolvoReg + MSQLR2.GetFloat("Kolvo");
}
MSQLR2.Dispose();
MSQLR2.Close();
MSQLR2 = null;

//сравнение остатка с количеством в накладной
if (Math.Round((float)ZakazdataGrid["Kolvo", q].Value, 3) > Math.Round(KolvoReg, 3))
{
Message MessForm = new Message();
MessForm.OpenForm("В строке " + (q + 1).ToString() + " количество превышает остаток (" + Math.Round(KolvoReg, 3).ToString() + ").", "Ошибка", 1, "OK", "");
ZakazdataGrid.Rows[q].Selected = true;
return 5;
}
}
//-------------------------------------------------------------------------------//
//ДАЛЬШЕ ИДЕТ ЗАПИСЬ ДАННЫХ В ТАБЛИЦЫ БД, НО ЕСЛИ ТОВАРА НЕТ НА ОСТАТКАХ, ТО КОД ВЫПОЛНЯТЬСЯ НЕ ДОЛЖЕН
//-------------------------------------------------------------------------------//
}
Commit(1);//---ВОТ ТУТ ТРАНЗАКЦИЯ ДЕЛАЕТ COMMIT---//

return 1;
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
conn.Dispose();
conn.Close();
conn = null;
}

}[/code]

Помогите пожалуйста разобраться в чем причина.

Для связи C# и MySQL использую конектор MySQL Connector Net 5.0.9.
БД - InnoDB


[Это сообщение - спам!]

Последние сообщения из форума

Уважаемые посетители форума MySQL.RU!
Убедительная просьба, прежде чем задавать свой вопрос в этом форуме, обратите внимание на разделы:
- ответы на наиболее часто задаваемые вопросы - FAQ
- раздел документация
- раздел поиск по сообщениям форума и документации
Также, старайтесь наиболее подробно указывать свою ситуацию (версию операционной системы, версию MySQL, версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
 Имя:
 E-mail:
 Тема:
 Текст:
Код подтверждения отправки: Code
37181



РЕКЛАМА НА САЙТЕ
  Создание сайтов | |