Здравствуйте, WFrag, Вы писали:
C>>А если подумать? C>>А если подумать, то при откате транзакции сумма блокируется до выяснения обстоятельств.
WF>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет?
Датчики это тут же зафиксируют.
Re[22]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, criosray, Вы писали:
WF>>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет? C>Датчики это тут же зафиксируют.
Датчики чего? Я вот не могу придумать способа заметить, что из середины что-то выдернули, не пересчитывая.
Re[5]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, March_rabbit, Вы писали:
C>>>>>(подсказка: бесконечный цикл) M_>>>>садитесь, два. M_>>>>Если бы Вы знали, как работает стэк, то поняли бы, что запись в array[4] затрет внешнюю (по отношению к циклу) переменную i, и никаким образом на количестве итераций не скажется. C>>>Опечатка конечно подразумевалось for (i = 0; A>>не-не, изначальный вариант тоже может вызвать зацикливание (при определенных условиях). M_>при каких?
ясное дело, если счётчик цикла будет в памяти сразу после array[3], и что он именно оттуда будет читаться. наличие внешней переменной с таким же именем тут при чем? и стэк тут совсем не причём, если конечно вы не покажете место в стандарте, где написано как компилятор должен складывать локальные переменные в стэк
это всё очень сильно компиляторнозависимое. я вполне себе воспроизвёл зацикливание с изначальным тестом, понятно что подобрав опции компилятора.
Re[15]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, _d_m_, Вы писали:
___>Нам хэндшейки нужны только на Commit-e. Больше нигде. Серверу вообще пофиг — что там у клиента исключение или что еще. Ему дали команду списать деньги, а дальше одно из двух — либо комит, либо ролбэк.
Коммит в какой момент? Когда бапки уже выдали клиенту? А если коммит не пройдет, получается мы бапки подарим. До выдачи? А если не получится выдать, по механическим причинам, а потом не пройдет обратная транзакция? Получается, что клиент подарит бапки нам.
Фактически, банкомат делает коммит, когда уже решил деньги отслюнавливать. Иногда у него не получается отслюнявить, тогда он делает обратную транзакцию. Я один раз такое видел, банкомат долго тарахтел деньгами, потом плюнул и сказал, что денег не даст. На счету было две транзакции: снятие и сразу возврат. Иногда обратная тракзакция не проходит, тогда у клиента начинается хождение по мукам
Pzz>>Поэтому гарантировать можно что-то одно из двух: либо что операция случится не более одного раза, либо что не менее одного раза. Но невозможно гаратнировать одновременно и то и то.
___>Ну конечно 100% нет. Но с учетом вышесказанного мной, здесь мы уже переходим в раздел вероятностей, где обезьяны печатают "Война и мир" случайными нажатиями.
Мне, кстати, навскидку непонятно, как организовать последовательность шагов в хендшейке так, чтобы получить вероятность ошибки хендшейка меньше, чем вероятность ошибки в одном шаге.
Re[2]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, Antikrot, Вы писали:
A>Здравствуйте, criosray, Вы писали:
C>>"Прелесть" С++ (кто представляет себе ассемблерный код после компиляции поймет что в таком случае произойдет): C>>
C>>int i;
C>>int array[4];
C>>for (int i = 0; i <= 4; i++) {
C>> array[i]=0;
C>>}
C>>
C>>(подсказка: бесконечный цикл) A>далеко не самый наглядный пример, если кто захочет проверить вероятность что счётчик цикла окажется сразу за array[3] и не будет загнан в регистр очень сильно не 100% A>компилятор + опции?
Это только усложняет дело. Иногда происходящая ошибка(одну версию собрали — нормально, что-то поменяли, компилятор скомпилил по-другому(регистры, например, нужны для другого) — глючит, что-то еще поменяли(но не устранили реальный источник проблемы) — компилятор снова по-другому расположил переменные, и все работает) на порядки хуже воспроизводимой всегда.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re[23]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, WFrag, Вы писали:
WF>>>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет? C>>Датчики это тут же зафиксируют.
WF>Датчики чего? Я вот не могу придумать способа заметить, что из середины что-то выдернули, не пересчитывая.
Ну Вы не можете, а те, кто делают банкоматы могут. Пачка денег в лотке зафиксированна под давлением. Если выдернуть купюру датчик тут же это определит.
Re[24]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, criosray, Вы писали:
WF>>>>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет? C>>>Датчики это тут же зафиксируют.
WF>>Датчики чего? Я вот не могу придумать способа заметить, что из середины что-то выдернули, не пересчитывая. C>Ну Вы не можете, а те, кто делают банкоматы могут. Пачка денег в лотке зафиксированна под давлением. Если выдернуть купюру датчик тут же это определит.
Здравствуйте, WFrag, Вы писали:
WF>Здравствуйте, criosray, Вы писали:
C>>А если подумать? C>>А если подумать, то при откате транзакции сумма блокируется до выяснения обстоятельств.
WF>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет?
Нет — это даже более невероятно, чем обези печатающие на машинках "В. и М.". Как будет в этом случае выглядеть претензия клиента?
Re[22]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, _d_m_, Вы писали:
WF>>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет?
___>Нет — это даже более невероятно, чем обези печатающие на машинках "В. и М.". Как будет в этом случае выглядеть претензия клиента?
Случайно — невероятно, специально — так делают (а потом пишут заявление, типа ничего не брал и всё тут).
Я просто пытаюсь доказать, что нет осбого смысла придумывать сложные схемы выдачи денег, всё равно 100% ACID-ность операции выдачи денег не получится. Проще просто забирать деньги обратно, без возврата на счёт, таким образом переложив эту проблему на клиента. А там уже и камеры в ход пойдут, и логи банкомата, и содержимое кассеты с невзятыми деньгами, и.т.д.
Re[18]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, criosray, Вы писали:
C>Здравствуйте, _d_m_, Вы писали:
___>>>>Ну конечно 100% нет. Но с учетом вышесказанного мной, здесь мы уже переходим в раздел вероятностей, где обезьяны печатают "Война и мир" случайными нажатиями.
G>>>Вроде существуют способы сделать 100% транзакционность в распределенной среде.
___>>Не верю! Невозможно.
C>Ну почему же, возможно, если речь о простом терминале, коим и является по сути банкомат. Транзакция коммитится только в случае, если от банкомата пришло подтверждение, что клиент забрал деньги из лотка.
А если вдуматься немножко глубже? А что если клиент забрал деньги из лотка, а связь в этот момент прервалась? Это не списание денег со счета, клиент (человек) как объект не участвует в транзакции и ему нельзя дать команду ролбэк.
Pzz прав, транзакцию надо фиксировать тогда, когда деньги лежат в лотке. Если деньги не забраны, то сторнировать.
И даже в этом случае у нас 100% гарантии.
1) клиент дает команду комит;
2) команда успешно доходит до сервера, он ее принимает, проводит практически транзакцию и блокирует ее ресусы до окончательного комита. Остается только поставить лекговесный флажок, сервер посылает клиенту, что мол коммит может быть успешен [1].
3) клиент посылает серверу подверждение[2], что [1] получил, вот тут и происходит реальный комит.
Но!
Сервер может не получить [2]. Или флажок завершения транзакции может быть не установлен из-за аварии. Что делать? Многократно обмениваться подверждениями, что подверждение подверждения о подверждении получено? Это опять не дает 100% гарантии — добро пожаловать в реальный мир (хотя даже то, что он реален не факт ). Вот это и есть самое слабое место транзакиции, и нет 100% протоколов.
Re[16]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, _d_m_, Вы писали:
___>>Нам хэндшейки нужны только на Commit-e. Больше нигде. Серверу вообще пофиг — что там у клиента исключение или что еще. Ему дали команду списать деньги, а дальше одно из двух — либо комит, либо ролбэк.
Pzz>Коммит в какой момент? Когда бапки уже выдали клиенту? А если коммит не пройдет, получается мы бапки подарим. До выдачи? А если не получится выдать, по механическим причинам, а потом не пройдет обратная транзакция? Получается, что клиент подарит бапки нам.
Pzz>Фактически, банкомат делает коммит, когда уже решил деньги отслюнавливать. Иногда у него не получается отслюнявить, тогда он делает обратную транзакцию. Я один раз такое видел, банкомат долго тарахтел деньгами, потом плюнул и сказал, что денег не даст. На счету было две транзакции: снятие и сразу возврат. Иногда обратная тракзакция не проходит, тогда у клиента начинается хождение по мукам
Да понятно, что в транзакции могут участвовать лишь объекты которые можно либо комитить, либо ролбэкнуть. Человек не может участвовать в транзакции — здесь только сторнирование.
Pzz>Мне, кстати, навскидку непонятно, как организовать последовательность шагов в хендшейке так, чтобы получить вероятность ошибки хендшейка меньше, чем вероятность ошибки в одном шаге.
Поэтому 2-х фазного протокола достаточно. Большей вероятности хоть при 500 фазном протоколе мы не получим.
PS: Приятно беседовать с умным человеком, который понимает с полуслова о чем речь
Re[23]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, WFrag, Вы писали:
WF>Здравствуйте, _d_m_, Вы писали:
WF>>>Тогда другой вариант. Из всей пачки денег клиент выдергивает 1 купюру из середины. Банкомат забирает деньги обратно, дальше что? Он их пересчитывать будет?
___>>Нет — это даже более невероятно, чем обези печатающие на машинках "В. и М.". Как будет в этом случае выглядеть претензия клиента?
WF>Случайно — невероятно, специально — так делают (а потом пишут заявление, типа ничего не брал и всё тут).
WF>Я просто пытаюсь доказать, что нет осбого смысла придумывать сложные схемы выдачи денег, всё равно 100% ACID-ность операции выдачи денег не получится. Проще просто забирать деньги обратно, без возврата на счёт, таким образом переложив эту проблему на клиента. А там уже и камеры в ход пойдут, и логи банкомата, и содержимое кассеты с невзятыми деньгами, и.т.д.
Ну это уже как-бы за рамками данного обсуждения. Ведь речь идет о распределенных транзакциях и о том, что может в ней участвовать.
Когда мне задают вопрос, а как ваша торговая система может защитить от воровства, если кассир не пробивает чек? Я отвечаю — от непробития чека вам не поможет любая торговая система.
Re[24]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, _d_m_, Вы писали:
___>Ну это уже как-бы за рамками данного обсуждения. Ведь речь идет о распределенных транзакциях и о том, что может в ней участвовать.
Я начал с того момента, где criosray «доработал» твой алгоритм.
Re[25]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, WFrag, Вы писали:
WF>Здравствуйте, _d_m_, Вы писали:
___>>Ну это уже как-бы за рамками данного обсуждения. Ведь речь идет о распределенных транзакциях и о том, что может в ней участвовать.
WF>Я начал с того момента, где criosray «доработал» твой алгоритм.
А вот так всегда в КСВ — вопрос: разница между трудноуловимым багом и исключениями перерос в то, что клиент сопрет купюру из серединки и скажет, что не брал. И более того найдутся апологеты которые скажут, что это косяк управляемых языков и исключения это гавно
Re[5]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, criosray, Вы писали:
C>Здравствуйте, March_rabbit, Вы писали:
M_>>Да и вообще, код безграмотный. С таким подходом в любом языке можно наваять фигню, послое чего смело утверждать, что язык — г.... C>С той разницей, что на С++ это гораздо легче сделать и сложнее отладить.
Да ну. Сразу получил исключение: Run-Time Check Failure #2 — Stack around the variable 'array' was corrupted. И остановка на выходе из ф-ции.
(еще и warning C4101: 'i' : unreferenced local variable). В общем код плохой, а не язык.
Все настроики компилятора по умолчанию(2005 студия).
Re[6]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, Antikrot, Вы писали:
A>Здравствуйте, March_rabbit, Вы писали:
C>>>>>>(подсказка: бесконечный цикл) M_>>>>>садитесь, два. M_>>>>>Если бы Вы знали, как работает стэк, то поняли бы, что запись в array[4] затрет внешнюю (по отношению к циклу) переменную i, и никаким образом на количестве итераций не скажется. C>>>>Опечатка конечно подразумевалось for (i = 0; A>>>не-не, изначальный вариант тоже может вызвать зацикливание (при определенных условиях). M_>>при каких? A>ясное дело, если счётчик цикла будет в памяти сразу после array[3], и что он именно оттуда будет читаться. наличие внешней переменной с таким же именем тут при чем?
гы. дело в том, что стек растет сверху-вниз. Соответственно, за краем массива окажется внешняя переменная i. А не внутренняя. Внешняя переменная будет затерта, здесь вопроса нет. Но на работу цикла это не повлияет.
A>и стэк тут совсем не причём, если конечно вы не покажете место в стандарте, где написано как компилятор должен складывать локальные переменные в стэк
ммм.. вопросов нет, все это — дело компилятора. Но, учитывая направление роста стэка, трудно придумать, зачем компилятор будет располагать переменные в другом порядке относительно прямого (то, в котором объявления этих переменных встречаются).
A>это всё очень сильно компиляторнозависимое. я вполне себе воспроизвёл зацикливание с изначальным тестом, понятно что подобрав опции компилятора.
забавно. И что это за опции? Опишите вкратце? Ибо я не очень представляю, как настолько изменить поведение программы
Re[7]: Модульные тесты и "безопасные" языки - хорошо.
Здравствуйте, March_rabbit, Вы писали:
M_>>>>>>Если бы Вы знали, как работает стэк, то поняли бы, что запись в array[4] затрет внешнюю (по отношению к циклу) переменную i, и никаким образом на количестве итераций не скажется. C>>>>>Опечатка конечно подразумевалось for (i = 0; A>>>>не-не, изначальный вариант тоже может вызвать зацикливание (при определенных условиях). M_>>>при каких? A>>ясное дело, если счётчик цикла будет в памяти сразу после array[3], и что он именно оттуда будет читаться. наличие внешней переменной с таким же именем тут при чем? M_>гы. дело в том, что стек растет сверху-вниз. Соответственно, за краем массива окажется внешняя переменная i. А не внутренняя. Внешняя переменная будет затерта, здесь вопроса нет. Но на работу цикла это не повлияет.
Представим другую ситуацию: внешняя переменная — некий аккумулятор, который наполняется в цикле. Предположим, что мы собираем и тестируем нашу программу определенным компилятором, который не сгенерирует код, способный затереть значение во внешнем аккумуляторе по выходу за границы массива (например, соптимизирует аккумулятор так, чтоб он постоянно находился в неком регистре). Все вроде отлично — программа работает... Но вот решаете Вы портировать Вашу программу, например, под другую платформу и для сборки используете уже другой компиллятор, который сгенерирует такой машинный код, что переменная-аккумулятор теперь станет затираться. Как же так, код, который годами работал и тут на тебе — сбоит на ровном месте!
А ведь вместо обычного целочисленного аккумулятора по тому адресу на стеке вполне мог быть, скажем, адрес zero-terminated строки и вот мы его затерли и он стал указывать совсем другой участок памяти... И еще очень хорошо будет, если тут же выскочит segment fault, а не что похуже...
Re: Модульные тесты и "безопасные" языки - хорошо.
Попробуйте скомпиллировать данный код в VC++ любой версии и запустить.
Сразу скажу, что код корректен.
#include"stdafx.h"#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
// Эта программа должна вывести /
// первые 8 чисел Фибоначчи: /
// 1, 1, 2, 3, 5, 8, 13, 21. /
// Определим первое и второе /
// значение ряда - это единицы: /int first = 1, second = 1;
// Сразу же выведем первое число: /
printf("%d, ", first);
// Цикл "делать следующее, пока /
// второе значение меньше 20". /while (second < 20) { // проверили/
// Следующее - это сумма /
// первого и второго. Вычислим /int next = first + second;
// Теперь надо записать второе /
// значение в первое, а следую- /
// щее - во второе, так ведь ???/
first = second;
second = next;
// Выведем на экран первое число/
printf("%d, ", first);
}
// Выведем последнее значение ряда/
printf("%d\n", second);
return 0;
}
Попробуйте без дебагера угадать в чем проблема. Удачи.
Re[7]: Модульные тесты и "безопасные" языки - хорошо.