Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Transactions on mysql adapter #41

Merged
merged 1 commit into from

2 participants

@davebcn

I'm integrating boss db on a project and I found that my boss_db transactions was not working properly.

I'm trying to do the following that simullates an error inside a transaction after a record insertion to force rollback:

boss_db:transaction(
    fun()->
    boss_db:save_record(transfer:new(id, "bbva", 0.11, "1112", "Transfer ref 44183781e", "pending", "0182-1004-93-0201538323", calendar:local_time(),undefined, "David Garcia",  "44183781e", undefined,<<"robot">>,false,undefined)),
    1 = 2
    end
).

Here we have mysql log with boss db before the patch :

MysqlLogPrePatch:

     1027 Query    BEGIN
     1028 Query    INSERT INTO transfers (had_error, transfer_type, dni, receiver, created_at, account, status, comments, reference, amount, bank_name) values (FALSE, 'robot', '44183781e', 'David Garcia', '2012-10-11 18:18:24', '0182-1004-93-0201538323', 'pending', 'Transfer ref 44183781e', '1112', 1.10000000000000000555e-01, 'bbva')
     1028 Query    SELECT last_insert_id()
     1027 Query    ROLLBACK

Here a transaction is started and ended on one connection, but statements are run on another . This is because executing the fun inside the mysql_conn makes that the transactional context set on boss_db is lost, so no transaction is performed.

To avoid this I moved transaction execution environment inside the mysql boss db adapter that performs the begin + yield + finish from the transaction and keeps the transactional context intact.

After the patch all the boss_db related code inside the transaction block uses the same transaction

MysqlLogPostPatch:

1026 Query BEGIN
1026 Query INSERT INTO transfers (had_error, transfer_type, dni, receiver, created_at, account, status, comments, reference, amount, bank_name) values (FALSE, 'robot', '44183781e', 'David Garcia', '2012-10-11 18:14:30', '0182-1004-93-0201538323', 'pending', 'Transfer ref 44183781e', '1112', 1.10000000000000000555e-01, 'bbva')
1026 Query SELECT last_insert_id()
1026 Query ROLLBACK
@evanmiller evanmiller merged commit 230f57a into ErlyORM:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 15, 2012
  1. moved transactions from mysql conn to mysql adapter

    Dave Garcia authored
This page is out of date. Refresh to see the latest.
Showing with 38 additions and 1 deletion.
  1. +38 −1 src/db_adapters/boss_db_adapter_mysql.erl
View
39 src/db_adapters/boss_db_adapter_mysql.erl
@@ -49,6 +49,7 @@ find(Pid, Type, Conditions, Max, Skip, Sort, SortOrder) when is_atom(Type), is_l
true ->
Query = build_select_query(Type, Conditions, Max, Skip, Sort, SortOrder),
Res = fetch(Pid, Query),
+
case Res of
{data, MysqlRes} ->
Columns = mysql:get_result_field_info(MysqlRes),
@@ -166,7 +167,43 @@ execute(Pid, Commands) ->
fetch(Pid, Commands).
transaction(Pid, TransactionFun) when is_function(TransactionFun) ->
- mysql_conn:transaction(Pid, TransactionFun, self()).
+ do_transaction(Pid, TransactionFun).
+
+do_transaction(Pid, TransactionFun) when is_function(TransactionFun) ->
+ case do_begin(Pid, self()) of
+ {error, _} = Err ->
+ {aborted, Err};
+ {updated,{mysql_result,[],[],0,0,[]}} ->
+ case catch TransactionFun() of
+ error = Err ->
+ do_rollback(Pid, self()),
+ {aborted, Err};
+ {error, _} = Err ->
+ do_rollback(Pid, self()),
+ {aborted, Err};
+ {'EXIT', _} = Err ->
+ do_rollback(Pid, self()),
+ {aborted, Err};
+ Res ->
+ case do_commit(Pid, self()) of
+ {error, _} = Err ->
+ do_rollback(Pid, self()),
+ {aborted, Err};
+ _ ->
+ {atomic, Res}
+ end
+ end
+ end.
+
+do_begin(Pid,_)->
+ fetch(Pid, ["BEGIN"]).
+
+do_commit(Pid,_)->
+ fetch(Pid, ["COMMIT"]).
+
+do_rollback(Pid,_)->
+ fetch(Pid, ["ROLLBACK"]).
+
% internal
Something went wrong with that request. Please try again.