Spring PlatformTransactionManager - 并发事务

时间:2017-12-04 12:10:22

标签: java spring concurrency transactions jdbctemplate

我正在实现一个JDBC数据库访问API(基本上是一个包装器),我使用Spring JdbcTemplatePlatformTransactionManager来处理事务操作。一切看起来都不错,但我无法理解jdbcTemplate如何管理并发事务。 我会根据学生的创作给你一个简化的例子,说明我的观点。让我们创造2个学生,约翰和杰克。第一个没有错误,秒有一个错误,下面是步骤和代码。

  • John开始交易
  • 执行John insert而不提交
  • 等待杰克插入
  • 杰克开始交易
  • 执行Jack插入时出现错误(age为null但数据库需要NON - NULL)
  • 回滚杰克交易
  • 提交John trasaction

StudentDAO

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

MainApp

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如何知道1个交易没问题,但另一个交易没有?尽管我们已经创建了2个事务,但JdbcTemplate将回滚Jack AND John事务,因为查询,执行和更新方法不需要TransactionStatus作为参数。这意味着Spring jdbcTemplate每次只支持1个事务?!

1 个答案:

答案 0 :(得分:1)

单个事务中的所有操作始终作为单个单元执行,因此全部将被提交或不提交。

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

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