2015-11-30 3 views
7

Я хава два jdbi дао, как эти:Использование @Transaction в применении JDBI/Dropwizard

public interface dao1 { 
    @Query("insert into table1 ...") 
    findByid(myBean1); 
} 

public interface dao2 { 
    @Query("insert into table2 ...) 
    save(myBean2; 
    } 
} 

я хочу, чтобы выполнить бросок из двух дао в одной сделке, как:

dao1.save(); 
dao2.save(); 

С весной я есть используется аннотация @transactional. Что я могу сделать с dropwizard и jdbi?

ответ

10

Вы можете использовать @Transaction в JDBI. Об этом я написал в блоге. http://manikandan-k.github.io/2015/05/10/Transactions_in_jdbi.html

+0

Привет, спасибо, это то, что мне нужно, но как я могу проверить класс, который реализует интерфейс GetHandle? Или если нужно использовать другой объект репозитория в одной транзакции? – LucaA

+0

Мы не можем использовать два разных хранилища в одной транзакции. Если вы хотите использовать два разных Дао, создайте репозиторий, содержащий эти два Daos. Для тестирования класса, с какими трудностями вы сталкиваетесь? – Manikandan

+0

, мы не можем издеваться над daos в модульном тесте репозитория, потому что им вводят jdbi @SqlCreateObject аннотацию и метод jdbi.onDemand. Это правда? – LucaA

-3

Применение @UnitOfWork

Пример:

@POST 
@UnitOfWork 
public Role create(@Valid RoleApi roleApi) { 
    return roleService.create(roleApi); 
} 
+1

@UnitOfWork аннотацию включена только с спящем связке, а не с jdbi один. – LucaA

1

В соответствии с jdbi документов,

обновление, вставка и операторы определения данных указаны в API объекта SQL с помощью @SqlUpdate аннотация. Методы для этих операторов должны иметь либо типы void, либо int return. Если тип возвращаемого значения - это int, значением будет количество измененных строк.

Аннотация: @SqlUpdate. Ниже приведен пример использования h2 в качестве базы данных.

DBI dbi = new DBI("jdbc:h2:mem:test"); 
Handle h = dbi.open(); 
Dao1 dao1 = h.attach(Dao1.class); 
dao1.save(myBean1); 

Ссылка: http://jdbi.org/sql_object_api_dml

2

SQL Object API Overview показывает возможность связывать два экземпляра одной и той же ручкой. Таким образом, вы можете как save() звонки в рамках одной и той же сделки:

// TODO: add try/catch/finally to close things properly 
DBI dbi = new DBI("jdbc:h2:mem:test"); 
Handle h = dbi.open(); 
h.begin(); 
Dao1 dao1 = h.attach(Dao1.class); 
Dao2 dao2 = h.attach(Dao2.class); 
dao1.save(myBean1); 
dao2.save(myBean2); 
h.commit(); 
h.close(); 

Если вы используете onDemand вместо open и стесняйтесь попробовать/поймать права, вы можете рассмотреть что-то вроде этого:

// add some more interfaces 
public interface Dao1 extends GetHandle, Transactional<Dao1> { 
    @Query("insert into table1 ...") 
    save(myBean1); 
} 

DBI dbi = new DBI("jdbc:h2:mem:test"); 
Dao1 dao1 = dbi.onDemand(Dao1.class); 

// no try/catch necessary here 
dao1.inTransaction(transactional, status) -> { 
    transactional.save(myBean1); 
    transactional.withHandle((h) -> h.attach(Dao2.class) 
     .save(myBean2)); 
    return null; // return is enforced by the interface 
}); 

Пожалуйста, дважды проверьте функциональность с помощью модульного теста.

0

Вы можете использовать транзакции обратного вызова на DBI:

dbi.useTransaction((handle, transactionStatus) -> { 
    Dao1 dao1 = handle.attach(Dao1.class); 
    Dao2 dao2 = handle.attach(Dao2.class); 
    dao1.save(); 
    dao2.save(); 
}); 

Предполагая, что вы используете JDBI V2.x