let*_*nje 9 java spring transactions jdbc rollback
我正在开发一个使用Spring IoC和JDBC Template类的Java应用程序.我有一个DAO类有4种方法:m1()到m4().m1在表t1上执行多次插入和更新,在t2上执行m2,在t3上执行m3等.
DAO方法使用如下:
while(true)
{
//process & generate data
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
//sleep
}
Run Code Online (Sandbox Code Playgroud)
我希望4个连续方法调用下的db操作是原子的,要么所有4个表都成功更新,要么都没有.因此,如果在m3()中执行操作时出错,我想回滚在m2和m1中执行的所有更改(更新和插入).
那么春天让你以下面的方式做到这一点?
while (true)
{
//process & generate data
transaction = TransactionManager.createNewTransaction();
transaction.start()
try
{
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
catch(DbUpdateException e)
{
transaction.rollBack();
}
transaction.end();
// sleep
Run Code Online (Sandbox Code Playgroud)
}
或者有更好的方法吗?
cle*_*tus 15
是Spring允许您以编程方式控制事务.
我个人更喜欢使用注释的声明式事务,如下所示:
public void runBatchJob() {
while (true) {
// generate work
doWork(unitOfWork);
}
}
@Transactional
private void doWork(UnitOfWork work) {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
Run Code Online (Sandbox Code Playgroud)
定义DAO函数的位置:
@Transactional
public void m1(Data data) {
...
}
Run Code Online (Sandbox Code Playgroud)
这需要在您的applicationContext.xml中:
<tx:annotation-driven/>
Run Code Online (Sandbox Code Playgroud)
声明性事务可以声明为需要事务,需要新事务,支持事务等.当使用@Transactionalthrow a 注释的块时,将发生回滚RuntimeException.
为了完整起见,程序化解决方案将是:
private TransactionTemplate transactionTemplate;
public setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
...
while (true) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
} catch(DbUpdateException e) {
status.setRollbackOnly();
}
}
});
}
Run Code Online (Sandbox Code Playgroud)