繁体   English   中英

使用Spring JDBC轻松进行交易?

[英]Easy transactions using Spring JDBC?

我正在开发一个使用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
}

我希望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

}

或者有更好的方法吗?

是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);
}

定义DAO函数的位置:

@Transactional
public void m1(Data data) {
  ...
}

这需要在您的applicationContext.xml中

<tx:annotation-driven/>

声明性事务可以声明为需要事务,需要新事务,支持事务等。当使用@Transactional注释的块抛出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();
      }
    }
  });
}

是的,您可以将这些调用放在方法中,并以声明方式指定您的事务。

您不需要添加该代码 - Spring可以为您完成。

如果您愿意,Spring可以通过使用@Transactional或XML来处理这一切。

要获得正确的导入事项是您想要的事务传播类型,这取决于您的应用程序。

默认情况下,如果某个事务不存在,则将启动该事务,并且如果已经启动了事务,则将重新使用现有事务。 如果您希望所有4个DAO都是原子的,那么这就是您想要的行为。

将@Transactional放在一个将管理名为(MyService)的DAO方法的类上 - 此层下面的任何内容现在都将参与该事务边界。

即:

@Transactional
public void m1(Data data) {
 ...
}

@Transactional
public void m2(Data data) {
 ...
}

在代码中执行此操作完全没必要。

有关详细信息,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM