沉睡森林@漂在北京

          本處文章除注明“轉(zhuǎn)載”外均為原創(chuàng),轉(zhuǎn)載請注明出處。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            152 隨筆 :: 4 文章 :: 114 評論 :: 0 Trackbacks

          今天發(fā)現(xiàn)一個奇怪的問題,Spring2.5的事物處理過程中,在web中事物控制無效,但是利用ClassPathXmlApplicationContext加載bean的方式可以進行事物控制。Web的代碼如下:

          /WEB-INF/SpringDemo-servlet.xml

          <?xml version="1.0" encoding="UTF-8"?>

          <beans

              xmlns="http://www.springframework.org/schema/beans"

              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

              xmlns:p="http://www.springframework.org/schema/p"

              xmlns:context="http://www.springframework.org/schema/context"

              xsi:schemaLocation="http://www.springframework.org/schema/beans

              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

              http://www.springframework.org/schema/context

              http://www.springframework.org/schema/context/spring-context-2.5.xsd">

             

                 <!-- :對web包中的所有類進行掃描,以完成Bean創(chuàng)建和自動依賴注入的功能 -->

              <context:component-scan base-package="com.example.springdemo"/>

           

              <!-- :啟動Spring MVC的注解功能,完成請求和注解POJO的映射 -->

              <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

           

              <!--  :對模型視圖名稱的解析,即在模型視圖名稱添加前后綴 -->

              <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"  p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>

                 

          </beans>

           

           

          Classpath: applicationContext.xml

          <?xml version="1.0" encoding="UTF-8"?>

          <beans xmlns="http://www.springframework.org/schema/beans"

                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                 xmlns:context="http://www.springframework.org/schema/context"

                 xmlns:tx="http://www.springframework.org/schema/tx"

                 xmlns:p="http://www.springframework.org/schema/p"

                 xsi:schemaLocation="http://www.springframework.org/schema/beans

                     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

                           http://www.springframework.org/schema/tx 

                       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

                     http://www.springframework.org/schema/context

                     http://www.springframework.org/schema/context/spring-context-2.5.xsd">

                      

                 <context:annotation-config />

             

                 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

                        destroy-method="close">

                        <property name="driverClassName" value="com.mysql.jdbc.Driver" />

                        <property name="url" value="jdbc:mysql://localhost/springdemo" />

                        <property name="username" value="root" />

                        <property name="password" value="sa" />

                 </bean>

                

                 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

                        <property name="dataSource" ref="dataSource" />

                 </bean>

                

                 <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

                

          <!--

                 利用ClassPathXmlApplicationContext方式加載時需要打開注釋

              <context:component-scan base-package="com.example.springdemo"/>

            -->    

          </beans>

           

          log4j.properties

          log4j.rootLogger=INFO, A1 , R

           

          log4j.logger.org.apache=INFO

           

          log4j.appender.A1=org.apache.log4j.ConsoleAppender

          log4j.appender.A1.layout=org.apache.log4j.PatternLayout

          log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

           

          log4j.appender.R=org.apache.log4j.RollingFileAppender

          log4j.appender.R.File=C:/OSWorkflowDemo.log

          log4j.appender.R.MaxFileSize=1000KB

          log4j.appender.R.MaxBackupIndex=1

          log4j.appender.R.layout=org.apache.log4j.PatternLayout

          log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

           

          測試的java函數(shù):

                 public static void main(String[] args) {

                        // TODO Auto-generated method stub

                        String [] conf = new String[2];

                        conf[0]="applicationContext.xml";

                        conf[1]="dataAccessContext-jdbc.xml";

                        ApplicationContext appContext = new ClassPathXmlApplicationContext(conf);

                        UserService us = (UserService) appContext.getBean("userService");

                        us.testTx();

                       

          //            System.out.println("hello");

                 }

          其他java類的主要函數(shù)如下:

          public interface UserService {

                 void testTx();

          }

           

          @Service("userService")

          public class UserServiceImpl implements UserService{

                 @Autowired

                 @Qualifier("userDao")

                 private UserDAO userDao;

                 public void testTx() {

                        userDao.insertTwoRecord();

                 }

          }

           

          public interface UserDAO {

                 void insertTwoRecord();

          }

           

          @Component("userDao")

          @Transactional

          public class UserDAOImpl   implements UserDAO{

                 private JdbcTemplate jdbcTemplate;

                 @Autowired

              public void setDataSource(@Qualifier("dataSource")DataSource dataSource) {

                  this.jdbcTemplate = new JdbcTemplate(dataSource);

              }

                 @Transactional(readOnly=false)

                 public void insertTwoRecord() {

                        System.out.println("hello ");

                        jdbcTemplate.execute("INSERT INTO USER(USERNAME,PASSWORD,EMAIL)VALUES('123','123','123')");

                        jdbcTemplate.execute("INSERT INTO USER(USERNAME,PASSWORD,EMAIL)VALUES('12322222222222222222','123','123')");

                 }

          }

           

           

          @Controller

          public class HelloController {

                 @Autowired

                 @Qualifier("userService")

                 private UserService userService;

                 @RequestMapping("/sayHello.do")

                 public String sayHello(ModelMap map,@RequestParam("id") Long userId){

                        map.put("username", "sayHello 1 ");

                        userService.testTx();

                       

                        return "sayHello";

                 }

                 @RequestMapping("/sayHello2.do")

                 public String sayHello2(ModelMap map,@RequestParam("name") String username){

                        map.put("username", username);

                        return "sayHello";

                 }

          }

           

          數(shù)據(jù)庫的腳本如下:

          CREATE TABLE `user` (

            `ID` int(11) NOT NULL auto_increment,

            `PASSWORD` varchar(10) default NULL,

            `USERNAME` varchar(16) NOT NULL,

            `EMAIL` varchar(64) default NULL,

            PRIMARY KEY  (`ID`)

          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

           

          Web.xml如下:

          <?xml version="1.0" encoding="UTF-8"?>

          <web-app version="2.4"

                 xmlns="http://java.sun.com/xml/ns/j2ee"

                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

                 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

                 <!--  Spring 服務層的配置文件 -->

              <context-param>

                  <param-name>contextConfigLocation</param-name>

                  <param-value>classpath:applicationContext.xml,classpath:dataAccessContext-jdbc.xml</param-value>

              </context-param>

              

              <!--  Spring 容器啟動監(jiān)聽器 -->

              <listener>

                  <listener-class>org.springframework.web.context.ContextLoaderListener

                  </listener-class>

              </listener>

           

              <!--  Spring MVC Servlet,它將加載WEB-INF/annomvc-servlet.xml

                    配置文件,以啟動Spring MVC模塊-->

              <servlet>

                  <servlet-name>SpringDemo</servlet-name>

                  <servlet-class>org.springframework.web.servlet.DispatcherServlet

                  </servlet-class>

                  <load-on-startup>0</load-on-startup>

              </servlet>

           

              <servlet-mapping>

                  <servlet-name>SpringDemo</servlet-name>

                  <url-pattern>*.do</url-pattern>

              </servlet-mapping>

           

            <welcome-file-list>

              <welcome-file>index.jsp</welcome-file>

            </welcome-file-list>

          </web-app>

           

          其中,dataAccessContext-jdbc.xml是個空文件,上面的配置沒有列出。在上面的代碼測試過程中,遇到了不少的問題,下面進行簡單的列舉。

          1、關于beans里面的xmlns=http://www.springframework.org/schema/beans錯誤,總是在提示出現(xiàn)錯誤。發(fā)現(xiàn)是lib下面的springjar包存在不同的版本,刪除jar包后重新加入一個spring的包后好了。

           

          2、后來出現(xiàn)了一個問題,錯誤提示信息沒有記下,反正在網(wǎng)上也是找到了解決的辦法。錯誤的原因是利用myeclipse加入了hibernatespringjar包,其中,asm系列的包有沖突,刪除之后好了。

           

          3、利用ClassPathXmlApplicationContext方式加載時需要加入 context:component-scan ,不然不能識別bean,并且在SpringDemo-servlet.xml文件中,必須有上面xml文件中的123.否則的話web模式下請求的url不被識別。

           

          4、最后一個問題還是最要命的,就是兩種bean的加載模式下,事物控制有效和無效。網(wǎng)上有人提出:估計spring初始化時優(yōu)先component-scan bean,注入Web Controller Service直接拿了上下文中的@Service("someService"),這個時候@Transactional (readOnly=false, isolation = Isolation.READ_COMMITTED) 還沒有被處理.所以Web Controller ServiceSomeServiceImpl而不是AOP$ProxyNO。提出的解決辦法是:不讓spring掃描到ServiceImpl,直接寫在xml文件,其它的配置和annotation照用,這樣事務就起作用了。這樣可以,但是service就必須寫在xml文件里面了。感覺不爽。

           

           

          posted on 2008-10-08 18:59 王總兵 閱讀(1350) 評論(0)  編輯  收藏 所屬分類: Spring
          主站蜘蛛池模板: 莒南县| 阳春市| 玛沁县| 长垣县| 子长县| 凤城市| 蒙山县| 怀化市| 延津县| 兴宁市| 贺州市| 随州市| 京山县| 黄冈市| 三河市| 右玉县| 鄂温| 玉门市| 永善县| 海林市| 临汾市| 蓝田县| 抚州市| 大理市| 钟祥市| 深泽县| 遂平县| 清河县| 松阳县| 家居| 邯郸市| 福清市| 昂仁县| 称多县| 南平市| 梁河县| 成都市| 湘乡市| 泉州市| 南汇区| 蓝山县|