当前位置: 首页 > 知识库问答 >
问题:

Spring PlatformTransactionManager-并发事务

万高轩
2023-03-14

我正在实现一个JDBC数据库访问API(基本上是一个包装器),我正在使用PlatformTransactionManager来处理事务操作。看起来一切正常,但我无法理解jdbcTemplate如何管理并发事务。为了说明我的观点,我将在学生创造的基础上给你们一个简单的例子。让我们创建两个学生,约翰和杰克。第一个没有错误,第二个只有一个错误,下面是步骤和代码。

  • 约翰开始交易

学生道

public class StudentJDBCTemplate implements StudentDAO {

   private DataSource dataSource;
   private JdbcTemplate jdbcTemplateObject;
   private PlatformTransactionManager transactionManager;

   // constructor, getters and setters

  public TransactionStatus startTransaction() throws TransactionException {
      TransactionDefinition def = new DefaultTransactionDefinition();
      transactionManager.getTransaction(def);
  }

  public void commitTransaction(TransactionStatus status) throws TransactionException {
      transactionManager.commit(status);
  }

  public void rollbackTransaction(TransactionStatus status) throws TransactionException {
      transactionManager.rollback(status);
  }

   public void create(String name, Integer age){
      String SQL1 = "insert into Student (name, age) values (?, ?)";
      jdbcTemplateObject.update( SQL1, name, age);
      return;
   }
}

主控制程序

public class MainApp {
    public static void main(String[] args){
        // setup db connection etc

       StudentJDBCTemplate studentDao = new StudentJDBCTemplate();

       TransactionStatus txJohn = studentDao.startTransaction();
       TransactionStatus txJack = studentDao.startTransaction();

       studentDao.create("John", 20);

       try {
           studentDao.create("Jack", null); // **FORCE EXCEPTION**
       } catch(Exception e){
           studentDao.rollback(txJack);
       }
       studentDao.commit(txJohn);
    }
}

JdbcTemplate如何知道一个事务正常,而另一个事务不正常?据我所知,尽管我们创建了2个事务,JdbcTemplate将回滚Jack和John事务,因为查询、执行和更新方法不需要TransactionStatus作为参数。这意味着SpringJDBCTemplate一次只支持一个事务?!

共有1个答案

师建德
2023-03-14

单个事务中的所有操作始终作为单个单元执行,因此要么提交所有操作,要么不提交任何操作。

如果John启动了一个插入然后更新的事务,那么两者(插入和更新)都将成功或没有,并且不会受到Jack启动的事务的影响。

现在,并发事务如何相互干扰由隔离级别控制,即一个事务如何看到另一个并发事务修改的数据。

 类似资料:
  • 我想知道如何使用hyperledger Composer在hyperledger fabric中执行并发事务。当我试图针对同一资源同时提交两个事务时,会出现以下错误:

  • 我有相同的模块,连接数据库运行在两个服务器(后台和前台)。它与同一个数据库连接。 我使用JPA(Hibernate实现)和Spring事务管理。 我有以下问题: 我必须用两个不同字段的最大值1更新表a中的字段a(表a中的字段a,表b中的字段b) 案例1: 更新前 表A fA = 100 tableB fB=102 更新后 表a fA=103 tableB fB=102 案例2: 更新前 表A fA

  • 我正在尝试用Connector/J和MySql构建一个Java(JDK1.8)应用程序。有人告诉我,Serializable是最高级别,但它会影响性能,所以Serializable并不常用。 但是考虑一下这种情况: 有两个提交将更新同一行的字段(提交A和提交B)。如果A和B同时发生,并且隔离级别不可序列化,则会出现数据竞争,这会导致字段不一致。但在可序列化级别,这两个更新不会同时发生,因此A发生在

  • 我试图使用在官方Fabriz-Samples存储库中找到的invoke函数同时向fabric提交两个事务。 你知道吗?

  • Hibernate 的事务和并发控制很容易掌握。Hibernate 直接使用 JDBC 连接和 JTA 资源,不添加任何附加锁定行为。我们强烈推荐你花点时间了解 JDBC 编程,ANSI SQL 查询语言和你使用的数据库系统的事务隔离规范。 Hibernate 不锁定内存中的对象。你的应用程序会按照你的数据库事务的隔离级别规定的那样运作。幸亏有了 Session,使得 Hibernate 通过标识

  • null Redis事务是有限的,无法特定键,并且所有键在上都不被监视;我们仅限于给定客户端上的单个正在进行的事务。 我见过许多redis用户声称lua脚本是他们所需要的全部的线程。甚至redis官方文档也表示,他们可能会删除交易,转而支持lua脚本。然而,有些情况下这是不够的,比如最标准的情况:使用redis作为缓存。 假设我们想从Redis中的持久数据存储中缓存一些数据。下面是一个快速的过程: