|
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,
версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
37181
|
|