使用 Spring JDBC 轻松事务?

发布于 2024-07-24 09:15:00 字数 944 浏览 4 评论 0原文

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

或者

有更好的方法吗?

I am working on a Java app that uses Spring IoC and JDBC Template classes. I have a DAO class that has 4 methods : m1() to m4(). m1 performs multiple inserts and updates on table t1, m2 on table t2, m3 on t3, etc.

The DAO methods are used as follows:

while(true)
{
  //process & generate data

  dao.m1(data1);
  dao.m2(data2);
  dao.m3(data3);
  dao.m4(data4);

  //sleep
}

I want the db operations under the 4 consecutive method calls to be atomic, either all the 4 tables are updated successfully or none are. So, if there is an error while performing operations in m3(), i want to rollback all the changes(updates & inserts) performed in m2 & m1.

So does spring let you do it the following way ?

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

}

or are there better ways to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滥情哥ㄟ 2024-07-31 09:15:00

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

Yes Spring allows you to programmatically control transactions.

Personally I prefer declarative transactions using annotations, which goes like this:

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

where the DAO functions are defined:

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

This requires in your applicationContext.xml:

<tx:annotation-driven/>

Declarative transactions can be declared to require a transaction, require a new transaction, support transactions, etc. Rollback will occur when a block annotated with @Transactional throws a RuntimeException.

水水月牙 2024-07-31 09:15:00

为了完整起见,程序化解决方案是:

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

For completeness, the programmatic solution would be:

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();
      }
    }
  });
}
野鹿林 2024-07-31 09:15:00

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

您不需要添加该代码 - Spring 可以为您做到这一点。

Yes, you can put those calls inside a method and specify your transactions declaratively.

You don't need to add that code - Spring can do it for you.

つ低調成傷 2024-07-31 09:15:00

Spring 可以通过使用@Transactional(如所解释的)或 XML(如果您愿意)为您处理这一切。

最重要的是您想要的事务传播类型,这完全取决于您的应用程序。

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

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

即:

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

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

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

请参阅此处了解更多信息

Spring can handle this all for you by using @Transactional as explained or in XML if you'd prefer.

The import thing to get right is the type of Transaction Propagation you want which all depends on your application.

By default a transaction will be started if one doesn't exist, and will re-use an existing transaction if one has already been started. This is the behavior you want if you want all 4 DAOs to be atomic.

Put @Transactional on a class which will manage the DAO methods called (MyService) - anything below this layer will now take part in that transaction boundary.

i.e:

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

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

Doing this in code is completely unnecessary.

See here for more info

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文