时间:2021-05-20
在描述问题之前先说明几个前提,假设在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包进行操作。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
在Spring中,DAO是DataAccessObject的简称,即,数据访问对象。它的名称虽然叫对象,但其实DAO是接口。这个名称很好的描述了DAO在程序中的
MyBatis-Spring允许你在ServiceBean中注入映射器。当使用映射器时,就像调用DAO那样来调用映射器就可以了,但是此时你就不需要进行任何DAO
前端直接绑定值,不传参数,controller中会一直取到初始化的值,无法实时获取前端select改变的值。解决方法一:前端调用方法的时候,一边传参数(亲测可用
Spring4.0MVC请求json数据报406错误,如何解决?解决方法一:1、导入jackson-core-2.5.1.jar和jackson-databin
本文实例讲述了Android编程中调用Camera时预览画面有旋转问题的解决方法。分享给大家供大家参考,具体如下:在调用Camera写应用的时候,前后摄像头的情