首页 新闻 搜索 专区 学院

DB2配置spring的托管事务时未设置事务的方法居然有事务的问题

0
悬赏园豆:20 [已解决问题] 解决于 2014-07-10 16:24

数据库使用DB2 V9.7

spring配置文件:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="login*" propagation="REQUIRED" />
            <tx:method name="regist*" propagation="REQUIRED" />
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- 配置那些类的方法进行事务管理 -->
    <aop:config>
        <aop:pointcut id="allManagerMethod" expression="execution (public * com.tf.zjjg..*.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" />
    </aop:config>

理论上除了save/delete/update/login/regist方法开启事务外,其他方法应该是只读事务,在只读事务中进行写操作应该是会报错的,可实际不是。

service方法:

com.tf.zjjg.quartz.service.impl.WeatherReadServiceImpl.readWeatherWithHttpUrl

com.tf.zjjg.quartz.service.impl.WeatherReadServiceImpl.readWeather

/**
     * 读取保存实时天气信息
     */
    @SuppressWarnings("rawtypes")
    public void readWeather() throws Exception {
        List allList = this.weatherReadDao.loadAllWeatherCityCode();
        
        int len = allList.size();
        List<WeatherAdminRelational> list = new ArrayList<WeatherAdminRelational>(len);

        for(int i=0; i<len; i++){
            list.add((WeatherAdminRelational)SQLUtils.coverMapToBean((Map)allList.get(i), WeatherAdminRelational.class));
        }
        readWeatherWithHttpUrl(list);
    }
    
    /**
     * 读取xml并保存,遇到出错进行异常的处理
     * @param list
     * @throws Exception
     */
    @Async
    private void readWeatherWithHttpUrl(List<WeatherAdminRelational> list){
        int index = 0;
        for(WeatherAdminRelational bean : list){
            index++;
            if(index>1){
                int k = 1/0; 
            }
            
            try{
                this.qsaveOneCityWeather(bean);
            }catch (Exception e) {
                this.qsaveErrorCode(bean.getWeatherCode(), e);
            }
        }
    }

上面的代码我把以save开头的方法都加了一个字母q来防止可能的事务,并且在循环执行一次后加了代码1/0使其报错,报错信息如下:

 1 15:56:49,572 DEBUG JobRunShell:198 - Calling execute on job DEFAULT.weatherTaskJob
 2 15:56:49,604 DEBUG DataSourceTransactionManager:365 - Creating new transaction with name [com.tf.zjjg.quartz.service.impl.WeatherReadServiceImpl.readWeather]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
 3 15:56:49,604 DEBUG DriverManagerDataSource:162 - Creating new JDBC DriverManager Connection to [jdbc:db2://10.10.62.179:50000/mysdedb]
 4 15:56:49,635 DEBUG DataSourceTransactionManager:204 - Acquired Connection [com.ibm.db2.jcc.c.b@1e8bcd60] for JDBC transaction
 5 15:56:49,635 DEBUG DataSourceUtils:153 - Setting JDBC Connection [com.ibm.db2.jcc.c.b@1e8bcd60] read-only
 6 15:56:49,635 DEBUG DataSourceTransactionManager:221 - Switching JDBC Connection [com.ibm.db2.jcc.c.b@1e8bcd60] to manual commit
 7 15:56:49,651 DEBUG SQLUtils:40 - select sql is:select * from T_WEATHER_ADMIN_RELATIONAL
 8 15:56:49,651 DEBUG JdbcTemplate:435 - Executing SQL query [select * from T_WEATHER_ADMIN_RELATIONAL]
 9 15:56:49,885  WARN WeatherReadServiceImpl:154 - 获取城市:101220102
10 15:56:49,900 DEBUG SQLUtils:54 - insert sql is:insert into T_WEATHER_READ(id,code,p_time,h,wd,fx,fl,js,sd,update_time,data_date) values (:id,:code,:pTime,:h,:wd,:fx,:fl,:js,:sd,:updateTime,:dataDate)
11 15:56:49,916 DEBUG JdbcTemplate:881 - Executing SQL batch update [insert into T_WEATHER_READ(id,code,p_time,h,wd,fx,fl,js,sd,update_time,data_date) values (?,?,?,?,?,?,?,?,?,?,?)]
12 15:56:49,916 DEBUG JdbcTemplate:570 - Executing prepared SQL statement [insert into T_WEATHER_READ(id,code,p_time,h,wd,fx,fl,js,sd,update_time,data_date) values (?,?,?,?,?,?,?,?,?,?,?)]
13 15:56:49,916 DEBUG JdbcUtils:362 - JDBC driver supports batch updates
14 15:56:49,947 DEBUG DataSourceTransactionManager:843 - Initiating transaction rollback
15 15:56:49,947 DEBUG DataSourceTransactionManager:279 - Rolling back JDBC transaction on Connection [com.ibm.db2.jcc.c.b@1e8bcd60]
16 15:56:49,947 DEBUG DataSourceUtils:222 - Resetting read-only flag of JDBC Connection [com.ibm.db2.jcc.c.b@1e8bcd60]
17 15:56:49,947 DEBUG DataSourceTransactionManager:322 - Releasing JDBC Connection [com.ibm.db2.jcc.c.b@1e8bcd60] after transaction
18 15:56:49,947 DEBUG DataSourceUtils:332 - Returning JDBC Connection to DataSource
19 15:56:49,963 ERROR JobRunShell:208 - Job DEFAULT.weatherTaskJob threw an unhandled Exception: 
20 org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'read' on target class [class com.tf.zjjg.quartz.task.WeatherReadTask] failed; nested exception is java.lang.ArithmeticException: / by zero
21     at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:320)
22     at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113)
23     at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
24     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)
25 Caused by: java.lang.ArithmeticException: / by zero
26     at com.tf.zjjg.quartz.service.impl.WeatherReadServiceImpl.readWeatherWithHttpUrl(WeatherReadServiceImpl.java:70)
27     at com.tf.zjjg.quartz.service.impl.WeatherReadServiceImpl.readWeather(WeatherReadServiceImpl.java:56)
28     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
29     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
30     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
31     at java.lang.reflect.Method.invoke(Method.java:606)
32     at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
33     at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
34     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
35     at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
36     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
37     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
38     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
39     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
40     at com.sun.proxy.$Proxy11.readWeather(Unknown Source)
41     at com.tf.zjjg.quartz.task.WeatherReadTask.read(WeatherReadTask.java:17)
42     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
43     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
44     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
45     at java.lang.reflect.Method.invoke(Method.java:606)
46     at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
47     at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:311)
48     ... 3 more

 

翻阅了该帖子:http://www.myexception.cn/software-architecture-design/922822.html

只读事务需要数据库来支持,但是我没对指定方法设置事务那spring也不应该帮我自动设置事务吧

问题补充:

修改

<tx:method name="*"  read-only="true" />

<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />

 

问题解决!!

自行车上的程序员的主页 自行车上的程序员 | 初学一级 | 园豆:198
提问于:2014-07-10 15:33
< >
分享
最佳答案
0

修改

<tx:method name="*"  read-only="true" />

<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />

 

问题解决!!

自行车上的程序员 | 初学一级 |园豆:198 | 2014-07-10 16:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册