Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用SpringJDBC轻松完成事务?_Java_Spring_Jdbc_Transactions_Rollback - Fatal编程技术网

Java 使用SpringJDBC轻松完成事务?

Java 使用SpringJDBC轻松完成事务?,java,spring,jdbc,transactions,rollback,Java,Spring,Jdbc,Transactions,Rollback,我正在开发一个使用Spring和JDBC模板类的Java应用程序。我有一个DAO类,它有4个方法:m1()到m4()。m1在表t1上执行多次插入和更新,m2在表t2上执行多次插入和更新,m3在表t3上执行多次插入和更新,等等 DAO方法使用如下: while(true) { //process & generate data dao.m1(data1); dao.m2(data2); dao.m3(data3); dao.m4(data4); //sleep

我正在开发一个使用Spring和JDBC模板类的Java应用程序。我有一个DAO类,它有4个方法:m1()到m4()。m1在表t1上执行多次插入和更新,m2在表t2上执行多次插入和更新,m3在表t3上执行多次插入和更新,等等

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中执行的所有更改(更新和插入)

那么spring是否允许您按照以下方式进行操作

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可以为您完成

是的,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中:



声明性事务可以声明为需要事务、需要新事务、支持事务等。当使用
@Transactional
注释的块抛出
运行时异常时,将发生回滚。为完整起见,编程解决方案将是:

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可以通过使用@Transactional(如所述)或XML(如果您愿意)来处理这一切

正确的导入方法是您想要的事务传播类型,这一切都取决于您的应用程序

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

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

i、 e:

在代码中这样做完全没有必要


请参见

我认为不需要将m1、m2等注释为@Transactional。如果任何人抛出异常,doWork已经完成的所有内容都将回滚。您不需要在此上下文中这样做,不需要。但是如果他们正在进行更新,您应该将其注释为需要事务,否则如果您在doWork()之外调用它们,您可能会发现自己正在进行非事务性更新当@Transactional注释应用于私有方法时,它有什么作用吗?是的,私有已不像以前那样私有了。:)
@Transactional
public void m1(Data data) {
 ...
}

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