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

Транзакции

22.09.2012, 21:47. Показов 5840. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru