evanmiller/boss_db — pull request #41 by davebcn (2012-10-15 15:14:09+00:00)
Title: Transactions on mysql adapter

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