/** * A convenience function which manages the lifecycle of a handle and yields it to a callback * for use by clients. The handle will be in a transaction when the callback is invoked, and * that transaction will be committed if the callback finishes normally, or rolled back if the * callback raises an exception. * * @param callback A callback which will receive an open Handle, in a transaction * @param <X> exception type thrown by the callback, if any. * * @throws X any exception thrown by the callback */ public <X extends Exception> void useTransaction(final HandleConsumer<X> callback) throws X { useHandle(handle -> handle.useTransaction(callback)); }
/** * A convenience function which manages the lifecycle of a handle and yields it to a callback * for use by clients. The handle will be in a transaction when the callback is invoked, and * that transaction will be committed if the callback finishes normally, or rolled back if the * callback raises an exception. * * <p> * This form accepts a transaction isolation level which will be applied to the connection * for the scope of this transaction, after which the original isolation level will be restored. * </p> * * @param level the transaction isolation level which will be applied to the connection for the scope of this * transaction, after which the original isolation level will be restored. * @param callback A callback which will receive an open Handle, in a transaction * @param <X> exception type thrown by the callback, if any. * * @throws X any exception thrown by the callback */ public <X extends Exception> void useTransaction(final TransactionIsolationLevel level, final HandleConsumer<X> callback) throws X { useHandle(handle -> handle.useTransaction(level, callback)); }
@Test public void testRollbackDoesntCommit() { assertThat(begin).isEqualTo(0); h.useTransaction(th -> { assertThat(begin).isEqualTo(1); assertThat(rollback).isEqualTo(0); th.rollback(); }); assertThat(rollback).isEqualTo(1); assertThat(commit).isEqualTo(0); }
@Test public void testRollbackFailDoesntLeak() throws Exception { final BoomHandler handler = new BoomHandler(); dbRule.getJdbi().setTransactionHandler(handler); final Handle h = dbRule.openHandle(); assertThat(h.isClosed()).isFalse(); handler.failRollback = true; assertThatThrownBy(() -> h.useTransaction(h2 -> h2.execute("insert into true"))) .isInstanceOf(UnableToCreateStatementException.class); assertThat(h.isInTransaction()) .describedAs("rollback failed but handle should still be in transaction").isTrue(); assertThatThrownBy(h::close) .isInstanceOf(CloseException.class); assertThat(h.isClosed()).isTrue(); assertThat(h.getConnection().isClosed()).isTrue(); }
@Before public void setUp() { handle.useTransaction(h -> { h.execute("DROP TABLE IF EXISTS users"); h.execute("CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR)"); for (String name : Arrays.asList("Alice", "Bob", "Charlie", "Data")) { h.execute("INSERT INTO users(name) VALUES (?)", name); } }); }
@Before public void setupDbi() { h = db.getHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS foo"); th.execute("CREATE TABLE foo (bar UUID, ary UUID[])"); }); }
@Before public void setUp() { h = db.getHandle(); h.useTransaction(th -> { th.execute("drop table if exists stuff"); th.execute("create table stuff (ts timestamp, d date, z text)"); }); }
@Before public void setUp() { h = dbRule.getSharedHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS uuids"); th.execute("CREATE TABLE uuids (u ARRAY)"); }); }
@Before public void setUp() { h = db.getHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS uuids"); th.execute("CREATE TABLE uuids (u UUID[], i INT[])"); }); ao = h.attach(ArrayObject.class); }
@Before public void setUp() { handle = postgresDbRule.getHandle(); handle.useTransaction(h -> { h.execute("drop table if exists campaigns"); h.execute("create table campaigns(id int not null, caps hstore)"); h.execute("insert into campaigns(id, caps) values (1, 'yearly=>10000, monthly=>5000, daily=>200'::hstore)"); h.execute("insert into campaigns(id, caps) values (2, 'yearly=>1000, monthly=>200, daily=>20'::hstore)"); }); }
@Before public void setUp() { handle = postgresDbRule.getHandle(); handle.useTransaction(h -> { h.execute("drop table if exists campaigns"); h.execute("create table campaigns(id int not null, caps hstore)"); h.execute("insert into campaigns(id, caps) values (1, 'yearly=>10000, monthly=>5000, daily=>200'::hstore)"); h.execute("insert into campaigns(id, caps) values (2, 'yearly=>1000, monthly=>200, daily=>20'::hstore)"); }); }
@Before public void setupDbi() { h = db.getHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS values"); th.execute("DROP TYPE IF EXISTS enum_t"); th.execute("CREATE TYPE enum_t AS ENUM ('FOO', 'BAR', 'BAZ')"); th.execute("CREATE TABLE values (value enum_t)"); }); }
@Before public void setUp() { Jdbi jdbi = Jdbi.create("jdbc:sqlite::memory:"); jdbi.installPlugin(new SQLitePlugin()); handle = jdbi.open(); handle.useTransaction(handle -> handle.execute("CREATE TABLE foo(url URL);")); }
@Before public void setUp() { dao = dbRule.getSharedHandle().attach(Dao.class); dbRule.getSharedHandle().useTransaction(h -> { h.execute("insert into something (id, name) values (1, 'Alice')"); h.execute("insert into something (id, name) values (2, 'Bob')"); h.execute("insert into something (id, name) values (3, 'Charles')"); }); }
@Test public void testTxnReentrant() { final TheBasics dao = db.onDemand(TheBasics.class); dao.withHandle(handle1 -> { handle1.useTransaction(h -> { dao.insert(new Something(1, "x")); List<String> rs = h.createQuery("select name from something where id = 1") .mapTo(String.class) .list(); assertThat(rs).hasSize(1); h.createQuery("SELECT 1").mapTo(int.class).list(); }); return null; }); }
@Before public void setUp() { dbRule.getJdbi() .registerArrayType(Integer.class, "integer") .registerArrayType(UUID.class, "uuid"); h = dbRule.openHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS arrays"); th.execute("CREATE TABLE arrays (u UUID[], i INT[])"); }); }
@Before public void setUp() { handle = postgresDbRule.getHandle(); handle.useTransaction(h -> { h.execute("drop table if exists intervals"); h.execute("create table intervals(id int not null, foo interval)"); // Can be periods. h.execute("insert into intervals(id, foo) values(1, interval '2 years -3 months 40 days')"); h.execute("insert into intervals(id, foo) values(2, interval '7 days')"); // Can't be. h.execute("insert into intervals(id, foo) values(3, interval '10 years -3 months 100 seconds')"); }); }
@Before public void setUp() { handle = postgresDbRule.getHandle(); handle.useTransaction(h -> { h.execute("drop table if exists intervals"); h.execute("create table intervals(id int not null, foo interval)"); // Can be durations. h.execute("insert into intervals(id, foo) values(1, interval '1 day 15:00:00')"); h.execute("insert into intervals(id, foo) values(2, interval '40 days 22 minutes')"); // Can't be. h.execute("insert into intervals(id, foo) values(3, interval '10 years -3 months 100 seconds')"); }); }
@Before public void setUp() { dao = dbRule.getSharedHandle().attach(Dao.class); dbRule.getSharedHandle().useTransaction(h -> { h.execute("insert into something (id, name) values (1, 'Alice')"); h.execute("insert into something (id, name) values (2, 'Bob')"); h.execute("insert into something (id, name) values (3, 'Charles')"); }); }
@Before public void setUp() { dbRule.getJdbi() .registerArrayType(Integer.class, "integer") .registerArrayType(UUID.class, "uuid"); h = dbRule.openHandle(); h.useTransaction(th -> { th.execute("DROP TABLE IF EXISTS arrays"); th.execute("CREATE TABLE arrays (u UUID[], i INT[])"); }); }