diff --git a/src/pgo.erl b/src/pgo.erl index d08a259..d6fcb68 100644 --- a/src/pgo.erl +++ b/src/pgo.erl @@ -173,23 +173,28 @@ new_transaction(Pool, Fun, Options) -> #{is_recording => if DoTrace -> true; true -> false end, attributes => TraceAttributes}, fun(_) -> - try - #{command := 'begin'} = pgo_handler:extended_query(Conn, "BEGIN", [], - #{queue_time => undefined}), - put(pgo_transaction_connection, Conn), - Result = Fun(), - case pgo_handler:extended_query(Conn, "COMMIT", [], - #{queue_time => undefined}) of - #{command := commit} -> Result; - #{command := rollback} -> Result - end - catch - Type:Reason:Stacktrace -> - pgo_handler:extended_query(Conn, "ROLLBACK", [], #{queue_time => undefined}), - erlang:raise(Type, Reason, Stacktrace) - after - checkin(Ref, Conn), - erase(pgo_transaction_connection) + Outcome = + try + #{command := 'begin'} = pgo_handler:extended_query(Conn, "BEGIN", [], + #{queue_time => undefined}), + put(pgo_transaction_connection, Conn), + Result = Fun(), + case pgo_handler:extended_query(Conn, "COMMIT", [], + #{queue_time => undefined}) of + #{command := commit} -> {committed, Result}; + #{command := rollback} -> rolled_back + end + catch + Type:Reason:Stacktrace -> + pgo_handler:extended_query(Conn, "ROLLBACK", [], #{queue_time => undefined}), + erlang:raise(Type, Reason, Stacktrace) + after + checkin(Ref, Conn), + erase(pgo_transaction_connection) + end, + case Outcome of + {committed, R} -> R; + rolled_back -> erlang:error(transaction_rolled_back) end end); {error, _}=E -> diff --git a/test/pgo_basic_SUITE.erl b/test/pgo_basic_SUITE.erl index a32fba4..736c4e0 100644 --- a/test/pgo_basic_SUITE.erl +++ b/test/pgo_basic_SUITE.erl @@ -19,7 +19,8 @@ groups() -> {domain_socket, [], [int4_range]}]. cases() -> - [exceptions, select, insert_update, text_types, + [transaction_returns_value, transaction_aborted_raises, + exceptions, select, insert_update, text_types, rows_as_maps, json_jsonb, types, int4_range, ts_range, tstz_range, numerics, hstore, records, circle, path, polygon, line, @@ -469,3 +470,21 @@ netmask(_Config) -> pgo:query("SELECT '192.168.0.1/24'::inet")), ok. + +transaction_returns_value(_Config) -> + ?assertEqual(42, pgo:transaction(fun() -> 42 end)), + ?assertEqual(ok, pgo:transaction(fun() -> + ?assertMatch(#{rows := [{1}]}, pgo:query("select 1::int")), + ok + end)), + ok. + +transaction_aborted_raises(_Config) -> + ?assertError(transaction_rolled_back, + pgo:transaction(fun() -> + {error, _} = pgo:query("select 1/0"), + ok + end)), + + ?assertMatch(#{rows := [{1}]}, pgo:query("select 1::int")), + ok.