程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Spring中DAO被循環調用的時候數據不實時更新的解決方法

Spring中DAO被循環調用的時候數據不實時更新的解決方法

編輯:JAVA編程入門知識

在描述問題之前先說明幾個前提,假設在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包進行操作。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved