📜 ⬆️ ⬇️

OLTP games

Recently, the topic of implementing high-performance applications has become popular on Habré. We also decided to experiment a little bit in this direction and share the current results of our research.

The “Hello, world!” Test subject is the simplest OLTP system:


')
Performance and resiliency requirements are key to such systems. Therefore, the search for a solution to the problem was carried out in the direction of: C, C ++, fastcgi, nginx, lighttpd, oracle. First of all, we were curious to try various options for building OLTP on these technologies, as well as measure performance and peak loads.


And so, the conditions of the problem


It is necessary to process transactions of the form: transfer X cu (money, but what did you think) from account A to account B. In order not to invent a bicycle and ensure scalability, the HTTP protocol was selected for interaction with the client.

Requests are


server.com/paysys.request?account=123&operator=456&money=789
which means: transfer 789 money from the account of the operator 456 to the account of the user 123.

There are only three labels in the database:


(Figure 1. Database structure)

The transaction procedure is not much more complicated than the database structure:
procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  1. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  2. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  3. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  4. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  5. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  6. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  7. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  8. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  9. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  10. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  11. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  12. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  13. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  14. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  15. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  16. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  17. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  18. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  19. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  20. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  21. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  22. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  23. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  24. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  25. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  26. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  27. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  28. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  29. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  30. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  31. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  32. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  33. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  34. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  35. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  36. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  37. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  38. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  39. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  40. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  41. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  42. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  43. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  44. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  45. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  46. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  47. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  48. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  49. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  50. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  51. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  52. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  53. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  54. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  55. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  56. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  57. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  58. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  59. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  60. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  61. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  62. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  63. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  64. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
  65. procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .
procedure PROCESS_TRANS(p_account_id in number, p_operator_id in number, p_sum in number, o_result out number) is l_cnt number; cursor cur_account is select id from pay_account where id = p_account_id for update of balance; cursor cur_operator is select id from pay_operator where id = p_operator_id and total >= p_sum for update of total; begin o_result := -1; -- tansaction begins select count (1) -- if such operator exist? into l_cnt from pay_operator opr where opr.id = p_operator_id; if (l_cnt != 1) then o_result := -2; -- Operator not found! return ; end if ; open cur_account; open cur_operator; fetch cur_account into l_cnt; -- need to fetch to update rows later fetch cur_operator into l_cnt; -- 0/1 row in cursor as selected by prim_key if cur_account%notfound then o_result := -3; -- Account not found! elsif cur_operator%notfound then o_result := -4; -- Operator has not enough money else update pay_account set balance = (balance + p_sum) where current of cur_account; update pay_operator set total = (total - p_sum) where current of cur_operator; insert into pay_transaction ( id, account_id, operator_id, money, datetime ) values ( pay_transaction_seq.nextval, p_account_id, p_operator_id, p_sum, sysdate ); commit ; o_result := 1; -- transaction successfully finished! end if ; close cur_account; close cur_operator; end ; * This source code was highlighted with Source Code Highlighter .


The most ideologically and practically correct approach to building a high-load server application with a large number of simultaneous connections is the implementation of the multiplexer ( The C10K problem ).
We decided to take the "unconventional" Oracle 10.2 Express Edition as the database. Transaction (update) in the database we performed for ~ 2 ms . At times, when Oracle flushed data to disk (apparently dbwr was writing modified data blocks from the buffer cache), the transaction was delayed to ~ 20 ms .

To connect to the database, we decided to use libraries from the manufacturer. As such, within our task, there were 2 jokes:OCCI, in the best OOP traditions, is much more visual and easy to use. However, its low-level counterpart has an undeniable advantage: OCI allows you to perform non-blocking (asynchronous) queries to the database, which is necessary to implement a multiplex server with multiple queries to the database as part of processing a single client. Many are unhappy that for the sake of the possibility of non-blocking calls, it is necessary to write a rather cumbersome code and ask Oracle to open the source code for OCCI, but, as far as I know, so far to no avail. In terms of performance, the 2 brothers differ very little, which is quite expected.

Ingredients:

dwelt on Ubuntu 9.04 under VMWare on an Acer 5920G laptop, for lack of any other hardware :). We hope the lack of resources (in both senses) did not affect the objectivity of the results of comparative tests, because all the tests were carried out in the same environment.

Immediately make a reservation that in setting up Oracle, we are far from Tom Kite, therefore, with tuning the database and operating system did not bother much. Let's do it when we move to a full server.

For the purity of the experiment, ~ 100k records were recorded in each tablet.

Experiences


How to build such a system? We first came to mind the simplest solution based on the FastCGI protocol. I think it’s not worth explaining once again how FastCGI differs from its progenitor CGI. For a high-loaded application, this difference is fundamental. I would like to dwell on another nuance, which we found out far from immediately.

The FastCGI specification provides for the preservation of a user connection for the possibility of implementing multiplexed processing of several requests simultaneously. In simple terms, you can call an asynchronous operation in the request handler and calmly give the processor time to other clients, and at the next iteration of the polling cycle get the result of the called operation and, sending the answer to the client, close the connection. Unfortunately, nginx and lighttpd (as well as the libfcgi and fastcgipp libraries) do not yet support this, demanding to close the connection before processing the next client.

However, in this example, we limited ourselves to only one short query to the database, which can be fully executed simultaneously, without fear of any significant loss in performance.

Nginx and lighttpd allow you to interact with FastCGI by two methods: via TCP channel and Unix Domain Socket. The advantage of the first approach is the possibility of clustering FastCGI servers, the disadvantage is the relatively high overhead of data transfer (TCP stack though). UDS, however, works only locally, due to which higher performance is ensured.

I would like to say a lot of “warm” words about the second method. After the first tests, it was found that almost a tenth of requests with more than 200 clients (on our hardware) reach the FastCGI application. The snag was in the net.unux.max_dgram_qlen kernel variable, which limits the size of the request queue when writing to the socket. By default, this option was 10, which explained the loss of requests. After setting the value to 10,000, everything seemed to return to normal. But it was not there. Almost a tenth of the requests were guaranteed to fall off, and nginx wrote terrible words “connect () to socket failed (11: Resource temporary unavailable)” in logia . In Russian, with a large number of simultaneous requests, the socket was “choking”. We have not yet been able to solve this problem. Although productivity has increased, but who needs it, when about 10% of transactions are completed with the “502” code.


FastCGI server:


  1. const char * bind_address = ": 9000" ;
  2. const char * db_user_name = "orauser" ;
  3. const char * db_password = "pass" ;
  4. const char * db_conn_str = "comp: 1521 / xe" ;
  5. int main ( int argc, char * const argv [])
  6. {
  7. using namespace oracle :: occi;
  8. int listenQueueBacklog = 4000;
  9. FCGX_Request request;
  10. if (FCGX_Init ())
  11. exit (1);
  12. int listen_socket = FCGX_OpenSocket (bind_address, listenQueueBacklog);
  13. if (listen_socket <0)
  14. exit (1);
  15. if (fchmod (listen_socket, S_IROTH | S_IWOTH))
  16. exit (1);
  17. if (FCGX_InitRequest (& request, listen_socket, 0)) exit (1);
  18. Environment * env = Environment :: createEnvironment (Environment :: DEFAULT);
  19. Connection * conn = env-> createConnection (db_user_name, db_password, db_conn_str);
  20. Statement * stmt = conn-> createStatement (
  21. "BEGIN PAY_SYS.PROCESS_TRANS (: v1,: v2,: v3,: v4); END;" );
  22. while (FCGX_Accept_r (& request) == 0)
  23. {
  24. bool noException = false , succesful = false ;
  25. long start = GetTickCount ();
  26. char * params = FCGX_GetParam ( "QUERY_STRING" , request.envp);
  27. int operatorID, accountID, moneySum, result = -1;
  28. operatorID = GetIntParam ( params , "operator =" );
  29. accountID = GetIntParam ( params , "account =" );
  30. moneySum = GetIntParam ( params , "money =" );
  31. if (operatorID <= 0 || accountID <= 0 || moneySum <= 0)
  32. {
  33. FCGX_FPrintF (request. Out , "HTTP / 1.0 503 Params Error \ n" );
  34. FCGX_FPrintF (request. Out , "Content-type: text / html \ r \ n \ r \ n" );
  35. FCGX_FPrintF (request. Out , "wrong params <br> \ n" );
  36. FCGX_Finish_r (& request);
  37. continue ;
  38. }
  39. try
  40. {
  41. stmt-> setInt (1, accountID);
  42. stmt-> setInt (2, operatorID);
  43. stmt-> setInt (3, moneySum);
  44. stmt-> registerOutParam (4, OCCIINT, sizeof (result));
  45. stmt-> execute ();
  46. result = stmt-> getInt (4);
  47. if (result == 1)
  48. succesful = true ;
  49. }
  50. catch (SQLException & sqlExcp)
  51. {
  52. error_log (sqlExcp.getMessage (). c_str ());
  53. }
  54. if (succesful)
  55. {
  56. FCGX_FPrintF (request. Out , "HTTP / 1.0 200 OK \ n" );
  57. FCGX_FPrintF (request. Out , "Content-type: text / html \ r \ n \ r \ n" );
  58. FCGX_FPrintF (request. Out , "SQL result =% d" , result);
  59. }
  60. else
  61. {
  62. FCGX_FPrintF (request. Out , "HTTP / 1.0 503 DatabaseError \ n" );
  63. FCGX_FPrintF (request. Out , "Content-type: text / html \ r \ n \ r \ n" );
  64. FCGX_FPrintF (request. Out , "Database error occured" );
  65. error_log ( "db error" );
  66. }
  67. FCGX_Finish_r (& request);
  68. }
  69. conn-> terminateStatement (stmt);
  70. env-> terminateConnection (conn);
  71. Environment :: terminateEnvironment (env);
  72. return 0;
  73. }
* This source code was highlighted with Source Code Highlighter .


Total


Used siege and ab. Due to memory problems, siege flatly refused to make more than 380 requests per second, while ab “squeezed” up to 1000 requests, but then referred to an excessive number of open sockets.

For the reliability of the results, testing was carried out according to the scheme of 10,000 queries at 100, 200, 300, 400 simultaneous. For FastCGI on this machine with default kernel settings, the loads were enough to overcome the critical threshold of 10% of lost requests. The lighttpd + fastcgi bundle began to “stumble” at ~ 200 requests, while the nginx bundle held up to ~ 300 simultaneous connections. With a load of more than 400 simultaneous connections, both FastCGI options fell off with the message “apr_poll: The timeout specified has expired (70007)”, while the nginx module without any screaming evened out with 1000 simultaneous connections via ab. The tests, again, rested against the "iron". For clarity, we decided to present the measurement results in the form of graphs.

So, on the x-axis - the number of simultaneous requests, on the y-axis - in accordance with the caption to the chart.


(Figure 2. The longest query, s)


(Figure 3. Average request processing time, sec.)


(Figure 4. The number of requests processed per second)


(Figure 5. Time spent on processing 10,000 requests, sec.)

Conclusion.


Resource limitations did not allow for overwhelming results, but we believe that comparative testing was entirely successful. Test results do not claim to be complete, but in general, in our opinion, confirm the expectations. Surely leading domestic athlete with a minimum of additional equipment. What a huge respect for him and his coach! In conjunction with FastCGI, he again bypasses a little bit of his foreign rival.

In our experiments, the mechanism of asynchronous calls to the database has not yet been used. It is curious how the test results will change if we complicate the processing of the client to several calls to the database and implement a full multiplexer. On FastCGI, this will not work, but this can be done with the nginx module, and also for completeness of the experiments, to call into the ranks of the "experimental" own HTTP daemon based on a library like poco, asio, pion ...

In general, to be continued ...

UPD
Nginx modules are server extensions statically compiled with it. Built-in functionality like SSL and FastCGI is also implemented as modules. Plus - speed, minus - the complexity of the update on a running machine. Excellent manuals are here .
A stripped-down example is below. For a change, work with ORACLE via the OCI C-library.
  1. // option WITHOUT setting support via nginx.conf and error PROCESSING
  2. #include <ngx_config.h>
  3. #include <ngx_core.h>
  4. #include <ngx_http.h>
  5. #include < string .h>
  6. #include <oci.h>
  7. const text * db_user_name = ( const text *) "orauser" ;
  8. const text * db_password = ( const text *) "pass" ;
  9. const text * db_conn_str = ( const text *) "comp: 1521 / xe" ;
  10. const text * command = ( const text *)
  11. "BEGIN PAY_SYS.PROCESS_TRANS (: v1,: v2,: v3,: v4); END;" ;
  12. OCIEnv * env;
  13. OCISvcCtx * context;
  14. OCISession * session;
  15. OCIServer * server;
  16. OCIError * error;
  17. OCIStmt * statement;
  18. OCIBind * bnd1, * bnd2, * bnd3, * bnd4;
  19. int operatorID, accountID, sum, result;
  20. static char * ngx_http_payment_init (ngx_conf_t * cf,
  21. ngx_command_t * cmd, void * conf);
  22. // array of possible module options in nginx.conf
  23. static ngx_command_t ngx_http_payment_commands [] =
  24. { // set only one main option, including the module in the specified Location
  25. {ngx_string ( "payment_enabled" ),
  26. NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
  27. ngx_http_payment_init,
  28. NGX_HTTP_LOC_CONF_OFFSET,
  29. 0,
  30. Null}
  31. ngx_null_command // terminates an array
  32. };
  33. // callback, don't use
  34. static ngx_http_module_t ngx_http_payment_module_ctx =
  35. {
  36. NULL, / * preconfiguration * /
  37. NULL, / * postconfiguration * /
  38. NULL, / * create main configuration * /
  39. NULL, / * init main configuration * /
  40. NULL, / * create server configuration * /
  41. NULL, / * merge server configuration * /
  42. NULL, / * create location configuration * /
  43. NULL / * merge location configuration * /
  44. };
  45. // module handle, includes all parameters
  46. ngx_module_t ngx_http_payment_module =
  47. {
  48. NGX_MODULE_V1,
  49. & ngx_http_payment_module_ctx, / * module context * /
  50. ngx_http_payment_commands, / * module directives * /
  51. NGX_HTTP_MODULE, / * module type * /
  52. NULL, / * init master * /
  53. NULL, / * init module * /
  54. NULL, / * init process * /
  55. NULL, / * init thread * /
  56. NULL, / * exit thread * /
  57. NULL, / * exit process * /
  58. NULL, / * exit master * /
  59. NGX_MODULE_V1_PADDING
  60. };
  61. void SetCallParams ( int oper, int account, int money)
  62. {
  63. if (bnd1! = 0) OCIHandleFree ((dvoid *) bnd1, OCI_HTYPE_BIND);
  64. if (bnd2! = 0) OCIHandleFree ((dvoid *) bnd2, OCI_HTYPE_BIND);
  65. if (bnd3! = 0) OCIHandleFree ((dvoid *) bnd3, OCI_HTYPE_BIND);
  66. if (bnd4! = 0) OCIHandleFree ((dvoid *) bnd4, OCI_HTYPE_BIND);
  67. // copy from the stack to be able to pass a valid pointer
  68. result = 0;
  69. operatorID = oper;
  70. accountID = account;
  71. sum = money;
  72. // bind the parameters to the SQL call
  73. OCIBindByPos (statement, & bnd1, error, 1, & accountID,
  74. sizeof (accountID), SQLT_INT, (dvoid *) 0,
  75. (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
  76. OCIBindByPos (statement, & bnd2, error, 2, & operatorID,
  77. sizeof (operatorID), SQLT_INT, (dvoid *) 0,
  78. (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
  79. OCIBindByPos (statement, & bnd3, error, 3, & sum, sizeof (sum), SQLT_INT,
  80. (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0,
  81. (ub4 *) 0, OCI_DEFAULT);
  82. OCIBindByPos (statement, & bnd4, error, 4, & result, sizeof (result), SQLT_INT,
  83. (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
  84. }
  85. // main handler, all work is done here
  86. static ngx_int_t ngx_http_payment_handler (ngx_http_request_t * r)
  87. {
  88. // clear the body section
  89. ngx_int_t rc = ngx_http_discard_request_body (r);
  90. if (rc! = NGX_OK && rc! = NGX_AGAIN)
  91. {
  92. ngx_log_error (NGX_LOG_ERR, r-> connection-> log, 0,
  93. "Failed ngx_http_discard_request_body ()" );
  94. return rc;
  95. }
  96. // strings in nginx are stored as a pair length-data,
  97. // not as traditional C-style zero-end
  98. // copy for the parser to work
  99. const int buflen = 100;
  100. char buf [buflen + 1];
  101. int len = (r-> args.len <buflen)? r-> args.len: buflen;
  102. buf [len] = '\ 0' ;
  103. ngx_memcpy (buf, r-> args.data, r-> args.len);
  104. int successful = 0;
  105. int operator , abonent, money, result = -1;
  106. // call the simplest parser
  107. operator = GetIntParam (buf, "operator =" );
  108. abonent = GetIntParam (buf, "abonent =" );
  109. money = GetIntParam (buf, "money =" );
  110. if ( operator > 0 && abonent> 0 && money> 0)
  111. {
  112. SetCallParams ( operator , abonent, money);
  113. int retCode = OCIStmtExecute (
  114. context, statement, error, (ub4) 1, (ub4) 0,
  115. (OCISnapshot *) NULL, (OCISnapshot *) NULL,
  116. (ub4) OCI_COMMIT_ON_SUCCESS);
  117. if (retCode == OCI_SUCCESS)
  118. successful = 1;
  119. }
  120. r-> headers_out.content_type.len = sizeof ( "text / html" ) - 1;
  121. r-> headers_out.content_type.data = (u_char *) "text / html" ;
  122. r-> headers_out.content_length_n = 0;
  123. if (successful == 1)
  124. r-> headers_out.status = NGX_HTTP_OK;
  125. else
  126. r-> headers_out.status = NGX_HTTP_INTERNAL_SERVER_ERROR;
  127. // ... forming the body of the response and sending it to nginx .. see emiller examples
  128. }
  129. static char * ngx_http_payment_init (ngx_conf_t * cf,
  130. ngx_command_t * cmd,
  131. void * our_conf)
  132. {
  133. // set nginx handler
  134. ngx_http_core_loc_conf_t * core_conf =
  135. ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
  136. core_conf-> handler = ngx_http_payment_handler;
  137. // oracle
  138. bnd1 = (OCIBind *) 0;
  139. bnd2 = (OCIBind *) 0;
  140. bnd3 = (OCIBind *) 0;
  141. bnd4 = (OCIBind *) 0;
  142. OCIEnvCreate ((OCIEnv **) & env, (ub4) OCI_DEFAULT,
  143. (dvoid *) 0, (dvoid * (*) (dvoid *, size_t)) 0,
  144. (dvoid * (*) (dvoid *, dvoid *, size_t)) 0,
  145. ( void (*) (dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0);
  146. / * allocate a server handle * /
  147. OCIHandleAlloc ((dvoid *) env, (dvoid **) & server,
  148. OCI_HTYPE_SERVER, 0, (dvoid **) 0);
  149. / * allocate an error handle * /
  150. OCIHandleAlloc ((dvoid *) env, (dvoid **) & error,
  151. OCI_HTYPE_ERROR, 0, (dvoid **) 0);
  152. / * create a server context * /
  153. int retCode = OCIServerAttach (server, error, db_conn_str,
  154. strlen (( const char *) db_conn_str), OCI_DEFAULT);
  155. / * allocate a service handle * /
  156. retCode = OCIHandleAlloc ((dvoid *) env, (dvoid **) & context,
  157. OCI_HTYPE_SVCCTX, 0, (dvoid **) 0);
  158. / * set the server attribute in the service context * /
  159. retCode = OCIAttrSet ((dvoid *) context, OCI_HTYPE_SVCCTX,
  160. (dvoid *) server, (ub4) 0, OCI_ATTR_SERVER, error);
  161. / * allocate a user session handle * /
  162. retCode = OCIHandleAlloc ((dvoid *) env, (dvoid **) & session,
  163. OCI_HTYPE_SESSION, 0, (dvoid **) 0);
  164. // set up user & password for our session
  165. retCode = OCIAttrSet ((dvoid *) session, OCI_HTYPE_SESSION,
  166. ( void *) db_user_name, (ub4) strlen (( const char *) db_user_name),
  167. OCI_ATTR_USERNAME, error);
  168. retCode = OCIAttrSet ((dvoid *) session, OCI_HTYPE_SESSION,
  169. ( void *) db_password, (ub4) strlen (( const char *) db_password),
  170. OCI_ATTR_PASSWORD, error);
  171. // start session
  172. retCode = OCISessionBegin (context, error, session,
  173. OCI_CRED_RDBMS, OCI_DEFAULT);
  174. / * set the user session attribute in the service context * /
  175. retCode = OCIAttrSet ((dvoid *) context, OCI_HTYPE_SVCCTX,
  176. (dvoid *) session, (ub4) 0,
  177. OCI_ATTR_SESSION, error);
  178. OCIHandleAlloc ((dvoid *) env, (dvoid **) & statement,
  179. OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
  180. OCIStmtPrepare (statement, error, command, (ub4) strlen (( char *) command),
  181. (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
  182. return NGX_CONF_OK;
  183. }
* This source code was highlighted with Source Code Highlighter .


Source: https://habr.com/ru/post/69974/


All Articles