Форум программистов, компьютерный форум, киберфорум
MySQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/30: Рейтинг темы: голосов - 30, средняя оценка - 5.00
 Аватар для МаксимТ
47 / 47 / 10
Регистрация: 17.08.2012
Сообщений: 225

Транзакции

22.09.2012, 21:47. Показов 5832. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть таблица, из двух полей (id - уникальный ключ, идентификатор пользователя и summ - количество денег)
Подскажите как правильно переводить деньги с одного счета на другой?
(предполагаю будет хранимая процедура, в которой транзакция)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.09.2012, 21:47
Ответы с готовыми решениями:

Транзакции
Есть две таблицы , в первой содержаться имена(Ваня, Андрей, Иван) , во второй их лицевой счет, как сделать так чтобы при изменении лицевого...

транзакции
нашел пример в интернете BEGIN TRANSACTION INSERT СОТРУДНИКИ (TAB) VALUES (5) INSERT ОТРАБОТАНО (TAB) VALUES (5) IF @@ERROR = 0 ...

Возможности транзакции
Всем привет, возможно ли сделать следущее с транзакциями, если нет, то подскажите как правильно сделать: В одном фрейме есть три...

5
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
23.09.2012, 06:34
Если минимально без лишних проверок (есть ли у первого пользователя достаточное количество средств), то что-то вроде этого:
MySQL
1
2
3
4
5
6
7
8
9
10
11
START TRANSACTION;
 
INSERT INTO `table` (`id`, `summ`)
VALUES (10, -42)
ON DUPLICATE KEY UPDATE `summ` = `summ` + VALUES(`summ`);
 
INSERT INTO `table` (`id`, `summ`)
VALUES (20, 42)
ON DUPLICATE KEY UPDATE `summ` = `summ` + VALUES(`summ`);
 
COMMIT;
10 - id первого пользователя, у которого отбираем деньги
20 - id второго пользователя, которому даём деньги
42 - сколько денег передаём

INSERT...ON DUPLICATE KEY UPDATE - на случае, если в таблице изначально не было инфы о данном пользователе.
Поскольку само число в VALUES уже при себе имеет нужный знак, в UPDATE оно в любом случае плюсуется.
Цитата Сообщение от МаксимТ Посмотреть сообщение
предполагаю будет хранимая процедура, в которой транзакция
Помните, что транзакции не могут быть вложенными. При запуске новой транзакции предыдущая автоматически commit'ится. Используйте SAVEPOINT при такой необходимости.
Помните, что у таблицы должен быть Engine=InnoDB.
2
 Аватар для МаксимТ
47 / 47 / 10
Регистрация: 17.08.2012
Сообщений: 225
23.09.2012, 12:42  [ТС]
хм, интересный способ. А как добавлять проверки?
(особо интересует проверка на отсутсвие пользователя - если нету то откатить транзакцию).
и как поведёт транзакция если первый или второй запрос провалятся(какие вобще могут быть ошибки?)?

p.s.
Выполнил такую транзакцию в базе - в результате создалось 2 записи(поскольку обе отсутсвовали)
значение денег у одного было 0(видимо изза того что деньги имеют атрибут unsigned) у другого 42
0
 Аватар для Vovan-VE
13210 / 6599 / 1041
Регистрация: 10.01.2008
Сообщений: 15,069
23.09.2012, 13:32
Цитата Сообщение от МаксимТ Посмотреть сообщение
и как поведёт транзакция если первый или второй запрос провалятся(какие вобще могут быть ошибки?)?
Ошибки могут быть какие угодно. Изменения в любом случае реально сохранятся только после commit'а, явного или неявного (неявный коммит - старт новой транзакции или один из некоторых запросов, который приводит к коммиту http://dev.mysql.com/doc/refma... ommit.html ). http://dev.mysql.com/doc/refman/5.1/en/commit.html
Цитата Сообщение от МаксимТ Посмотреть сообщение
Выполнил такую транзакцию в базе - в результате создалось 2 записи(поскольку обе отсутсвовали)
Все правильно. Там же запрос INSERT ON DUPLICATE KEY UPDATE. Полагалось, что по умолчанию у всех 0 денег и это не обязательно хранить, раз уж id юзера в таблице уникален.
Цитата Сообщение от МаксимТ Посмотреть сообщение
значение денег у одного было 0(видимо изза того что деньги имеют атрибут unsigned)
Да, если на долги не ориентироваться, можно допустить глупую утечку денег. Надо быть вдвойне внимательнее, чем обычно.
Цитата Сообщение от МаксимТ Посмотреть сообщение
А как добавлять проверки?
Могу ошибиться, пишу почти наугад.
MySQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
DELIMITER ;;
 
CREATE PROCEDURE `move_money` (
    IN `fromUser` INT(10),
    IN `toUser` INT(10),
    IN `amount` DECIMAL(12,3) UNSIGNED
) MODIFIES SQL DATA
BEGIN
    START TRANSACTION;
 
    SET @is_allowed = FALSE;
 
    SELECT `amount` > 0 AND `summ` >= `amount`
    INTO @is_allowed
    FROM `table`
    WHERE `id` = `fromUser`
    FOR UPDATE;
 
    IF @is_allowed IS TRUE THEN
 
        INSERT INTO `table` (`id`, `summ`) VALUES (`fromUser`, -`amount`)
        ON DUPLICATE KEY UPDATE `summ` = `summ` + VALUES(`summ`);
 
        INSERT INTO `table` (`id`, `summ`) VALUES (`toUser`, `amount`)
        ON DUPLICATE KEY UPDATE `summ` = `summ` + VALUES(`summ`);
 
        COMMIT;
    ELSE
        ROLLBACK;
    END IF;
END;;
MySQL
1
2
-- от юзера 10 к юзеру 20 передам 42.37 денег
CALL `move_money`(10, 20, 42.37);
3
576 / 514 / 253
Регистрация: 26.09.2010
Сообщений: 2,603
03.12.2013, 15:55
Приветствую пользователей форума!
Помогите пожалуйста с транзакциями, задача заключается в следующем есть две связанные таблицы по ID первой, как мне при записи в БД взять ID первой таблицы и поместить его во вторую... вот что я написал, тут не работает так как мне надо, здесь выполняется вставка в таблицы, но ID первой таблицы во вторую не заноситься, заноситься постоянно ноль

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php
    if (!empty($_POST['saglabat']))
    {
        $pfname = htmlspecialchars($_POST['pfname']);
        $plname = htmlspecialchars($_POST['plname']);
        $ptevaname = htmlspecialchars($_POST['ptevaname']);
        $pdzimums = htmlspecialchars($_POST['pdzimums']);
        $pdzdate = htmlspecialchars($_POST['pdzdate']);
        $pvalsts = htmlspecialchars($_POST['pvalsts']);
        $padrese = htmlspecialchars($_POST['padrese']);
        $ppazimes = htmlspecialchars($_POST['ppazimes']);
        $ppiezimes = htmlspecialchars($_POST['ppiezimes']);
        //------------------------Aiztureshana
        $strukturvieniba = htmlspecialchars($_POST['strukturvieniba']);
        $protokola_datums = htmlspecialchars($_POST['protokola_datums']);
        $protokola_nr = htmlspecialchars($_POST['protokola_nr']);
        $pamatojums = htmlspecialchars($_POST['pamatojums']);
        $aiztureshanas_piezimes = htmlspecialchars($_POST['aiztureshanas_piezimes']);
        $parvalde = htmlspecialchars($_POST['parvalde']);
        
        
        //require('setup.php');
        //$db = db_connect('dap_aaic_is');
 
        try
{ 
  $dbh = new PDO ( 'mysql:dbname=dap_aaic_is' , 'root' , '' , 
                   array( PDO :: ATTR_PERSISTENT => true )); 
  echo "Есть контакт! Поехали…" ; 
}
catch ( Exception $e )
{ 
  die( "Соединение не прошло: " . $e -> getMessage ()); 
} 
        
        
try
{ 
  $dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION ); 
 
  $dbh -> beginTransaction (); 
  $dbh -> exec ("INSERT INTO PERSONAS_PAMATDATI (pid, pfname, plname, ptevaname, pdzimums, pdzdate, pvalsts, padrese, ppazimes, ppiezimes) 
VALUES ('".$pfname."',
        '".$plname."', 
        '".$ptevaname."',
        '".$pdzimums."',
        '".$pdzdate."',
        '".$pvalsts."',
        '".$padrese."',
        '".$ppazimes."',
        '".$ppiezimes."');");
        
        $newpid = mysql_insert_id();
        
  $dbh -> exec ("INSERT INTO AIZTURESHANA (pid, parvalde, strukturvieniba, protokola_datums, protokola_nr, pamatojums, piezimes) 
VALUES ('".$newpid."',
        '".$parvalde."', 
        '".$strukturvieniba."',
        '".$protokola_datums."',
        '".$protokola_nr."',
        '".$pamatojums."',
        '".$aiztureshanas_piezimes."');");
  $dbh -> commit (); 
}
catch ( Exception $e )
{ 
  $dbh -> rollBack (); 
  echo "Шеф! Фсё пропало : " . $e -> getMessage (); 
} 
        
                        
    //mysql_close($dbh);    
    
    } ;
    
?>
подскажите как решить эту проблему
0
576 / 514 / 253
Регистрация: 26.09.2010
Сообщений: 2,603
05.12.2013, 11:43
Цитата Сообщение от Виталюска Посмотреть сообщение
Приветствую пользователей форума!
Помогите пожалуйста с транзакциями, задача заключается в следующем есть две связанные таблицы по ID первой, как мне при записи в БД взять ID первой таблицы и поместить его во вторую... вот что я написал, тут не работает так как мне надо, здесь выполняется вставка в таблицы, но ID первой таблицы во вторую не заноситься, заноситься постоянно ноль

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php
    if (!empty($_POST['saglabat']))
    {
        $pfname = htmlspecialchars($_POST['pfname']);
        $plname = htmlspecialchars($_POST['plname']);
        $ptevaname = htmlspecialchars($_POST['ptevaname']);
        $pdzimums = htmlspecialchars($_POST['pdzimums']);
        $pdzdate = htmlspecialchars($_POST['pdzdate']);
        $pvalsts = htmlspecialchars($_POST['pvalsts']);
        $padrese = htmlspecialchars($_POST['padrese']);
        $ppazimes = htmlspecialchars($_POST['ppazimes']);
        $ppiezimes = htmlspecialchars($_POST['ppiezimes']);
        //------------------------Aiztureshana
        $strukturvieniba = htmlspecialchars($_POST['strukturvieniba']);
        $protokola_datums = htmlspecialchars($_POST['protokola_datums']);
        $protokola_nr = htmlspecialchars($_POST['protokola_nr']);
        $pamatojums = htmlspecialchars($_POST['pamatojums']);
        $aiztureshanas_piezimes = htmlspecialchars($_POST['aiztureshanas_piezimes']);
        $parvalde = htmlspecialchars($_POST['parvalde']);
        
        
        //require('setup.php');
        //$db = db_connect('dap_aaic_is');
 
        try
{ 
  $dbh = new PDO ( 'mysql:dbname=dap_aaic_is' , 'root' , '' , 
                   array( PDO :: ATTR_PERSISTENT => true )); 
  echo "Есть контакт! Поехали…" ; 
}
catch ( Exception $e )
{ 
  die( "Соединение не прошло: " . $e -> getMessage ()); 
} 
        
        
try
{ 
  $dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION ); 
 
  $dbh -> beginTransaction (); 
  $dbh -> exec ("INSERT INTO PERSONAS_PAMATDATI (pid, pfname, plname, ptevaname, pdzimums, pdzdate, pvalsts, padrese, ppazimes, ppiezimes) 
VALUES ('".$pfname."',
        '".$plname."', 
        '".$ptevaname."',
        '".$pdzimums."',
        '".$pdzdate."',
        '".$pvalsts."',
        '".$padrese."',
        '".$ppazimes."',
        '".$ppiezimes."');");
        
        $newpid = mysql_insert_id();
        
  $dbh -> exec ("INSERT INTO AIZTURESHANA (pid, parvalde, strukturvieniba, protokola_datums, protokola_nr, pamatojums, piezimes) 
VALUES ('".$newpid."',
        '".$parvalde."', 
        '".$strukturvieniba."',
        '".$protokola_datums."',
        '".$protokola_nr."',
        '".$pamatojums."',
        '".$aiztureshanas_piezimes."');");
  $dbh -> commit (); 
}
catch ( Exception $e )
{ 
  $dbh -> rollBack (); 
  echo "Шеф! Фсё пропало : " . $e -> getMessage (); 
} 
        
                        
    //mysql_close($dbh);    
    
    } ;
    
?>
подскажите как решить эту проблему
Проблема решена
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.12.2013, 11:43
Помогаю со студенческими работами здесь

Транзакции и блокировки
Привет. Есть две транзакции: T1 (запускается первой) всегда REPEATABLE READ 1) Обновление table_1 2) Запуск T2 2) Обновление...

MyISAM транзакции
Я намерено вызываю ошибку при регистрации, но запись пользователя все равно появляется в БД, что я делаю не так? По логике добавление...

Изоляция в транзакции
Добрый день. Вопрос простой. Есть некая последовательность: 1. Запрос на получение количество строк в одной из таблиц 2. Insert в...

SELECT + Транзакции
Доброго времени суток! И так, в процессе разработки появилась задача записи информации в несколько таблиц БД с учетом нескольких проверок...

Откат транзакции
Расскажу суть проблемы на примере. 1. Создаю таблицу CREATE TABLE tab ( id INT, name CHAR(32) NOT NULL, PRIMARY KEY(id) ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 01.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 31.01.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru