2016-11-30 64 views
0

我对spring引导代码有问题。我想了解与@Transactional注释隔离级别,并给出验证码:隔离级别可重复读取弹簧引导

//BookingService class bookingService2 instance 
    @Transactional(isolation = Isolation.REPEATABLE_READ) 
    public String readConstantly() throws InterruptedException { 
     String name = ""; 
     for(int i=0; i<2; i++) { 
      name = jdbcTemplate.query("select FIRST_NAME from BOOKINGS where ID=1", (rs, rowNum) -> rs.getString("FIRST_NAME")).get(0); 
      logger.info("Read name " + name); 
      Thread.sleep(1000); 
     } 

     return name; 
    } 

和验证码:

//BookingService class bookingService instance 
@Transactional 
public void updateOne(){ 
    jdbcTemplate.update("update BOOKINGS set FIRST_NAME = ? where ID = 1", "zz"); 
} 

有了执行这样的:

new Thread(() -> { 
      try { 
       bookingService2.readConstantly(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     }).start(); 

     bookingService.updateOne(); 

我希望updateOne等到read持续交易结束,但是当我调用它时,这是输出:

2016-11-30 12:29:15.158 INFO 6456 --- [  Thread-3] hello.BookingService      : Read name Alice 
2016-11-30 12:29:16.158 INFO 6456 --- [  Thread-3] hello.BookingService      : Read name zz 

我试图理解为什么在这种情况下隔离级别没有太多的工作?

+0

你在用什么db? – dimitrisli

+0

我使用嵌套的H2数据库 –

回答

0

看着,看来H2不支持可重复读取。您可能需要使用“可序列化”来代替。

+0

嗨,它仍然不起作用。什么更好,我只是增加了SET LOCK_MODE 1;在sql模式脚本中,甚至可以通过获取数据源并设置隔离级别((org.apache.tomcat.jdbc.pool.DataSource)template.getDataSource())。setDefaultTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);它仍然没有按预期工作。可能是因为使用JDBCTemplate而不是普通的jdbc?此外,我甚至检查了从txmanager和jdbctemplate引用的数据源,这些都是一样的 –