Spring中DAO被循环调用的时候数据不实时更新的解决方法

所属分类: 软件编程 / java 阅读数: 40
收藏 0 赞 0 分享

在描述问题之前先说明几个前提,假设在Spring的配置文件中使用下面的方式配置了数据库的事务:

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource" ref="dataSource"/>
 </bean> 
 <tx:annotation-driven transaction-manager="transactionManager" />

现在有UserDao和SecurityService:

@Repository
 public class UserDao {
   public User getUser() {
     // query user from user table
     return queryObject("select * from user order by id desc limit 1");
   }
 }
@Service
 @Transactional
 public class SecurityService {
   @Autowired
   private UserDao userDao;
 
   public void checkUserInfo() {
     while(true) {
       User user = userDao.getUser();
       if(user != null && "Tom".equals(user.getName()) {
         System.out.println("Tom is here");
         break;
       }
     }
   }
 }

在调用SecurityService#checkUserInfo()方法的过程中,通过userDao#getUser()方法获取到的数据是不变的,即使这个时候新插入了一条name为Tom的数据循环也不会结束。另外将SecurityService上面的@Transactional注解去掉也无济于事。
首先想到会不会是数据库连接池的问题,换成了Spring自带的也是如此;然后从JdbcTemplate里面直接调用了Connection对象,使用原始的JDBC方式操作数据库,这个时候数据是实时变化的,于是想到应该是Spring的事务和当前操作线程进行绑定了。查看源代码进入之后果然在DataSourceUtils#doGetConnection方法里面发现了Spring在每个线程的每个DataSource上创建了一个Connection并且与事务进行了绑定。因为tx:annotation-driven配置文件对所有的Service层(加了@Service注解的类)进行了事务绑定,所以无论是否使用@Transactional都在同一个线程中绑定了同一个Connection,只是不进行事务操作而已。
经过多次实验和查找资料,最后终于找到了完美的解决方法:只要在上述的checkUserInfo方法中加上 @Transactional(propagation = Propagation.NOT_SUPPORTED) 注解就可以了。当然也可以获取到Connection然后手工进行操作,也可以使用DateUtils包进行操作。

更多精彩内容其他人还在看

java 中maven pom.xml文件教程详解

这篇文章主要介绍了java 中maven pom.xml文件教程详解,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

spring boot整合netty的实现方法

这篇文章主要介绍了spring boot整合netty的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Netty与Spring Boot的整合实现

这篇文章主要介绍了Netty与Spring Boot的整合的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring动态加载bean后调用实现方法解析

这篇文章主要介绍了Spring动态加载bean后调用实现方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享

java实现画图板上画一条直线

这篇文章主要为大家详细介绍了java实现画图板上画一条直线,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java通过python命令执行DataX任务的实例

今天小编就为大家分享一篇Java通过python命令执行DataX任务的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

springBoot集成redis的key,value序列化的相关问题

这篇文章主要介绍了springBoot集成redis的key,value序列化的相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

java实现登录案例

这篇文章主要为大家详细介绍了java实现登录案例的相关代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java解决请求跨域的两种方法

这篇文章主要为大家详细介绍了java解决请求跨域的两种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SpringBoot集成Beetl后统一处理页面异常的方法

这篇文章主要介绍了SpringBoot集成Beetl后统一处理页面异常的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享
查看更多