前面讲了两大类,四种spring事务的方式。这篇主要记录基于注解的springmvc+声明式或者注解式事务。
基于注解的就只要把<tx:advice>注销掉。改成<tx:annotation-driven transaction-manager="transactionManager" />就行。
注意的是。在applicationContext.xml中的和[servlet-name]-servlet.xml中的<component-scan>。在前者中,没有包含控制器的包。如果包含,则事务不起作用。具体原因是:
服务器启动加载配置文件的顺序为web.xml---->applicationContext.xml(spring的配置文件)---->[servlet-name]-servlet.xml(springmvc配置文件)。由于applicationContext.xml配置文件中Controller会先进行扫描装配,但是此时Service还没有进行事务增加处理,得到的将是原来的Service(没有经过事务增强处理,故而没有事务处理能力)
所以,在applicationContext.xml中一定要先扫描非Controller中的包。而在[servlet-name]-servlet.xml中扫描Controller中的包。可以是我例子中的那样,也可以这样:
applicationContext.xml中
<context:component-scan base-package="com" > <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan>
[servlet-name]-servlet.xml中
<context:component-scan base-package="com" use-default-filters="false" > <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan>
具体例子如下:使用的方式没有上面那个简便。但是用来实验也还可以。
package cn.lyy.model; import org.springframework.stereotype.Component; @Component public class Teacher { private int id; private String name; private String email; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
package cn.lyy.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import cn.lyy.dao.TeacherDao; import cn.lyy.model.Teacher; @Service public class TeacherService { @Autowired private TeacherDao teacherDao; public void addTeacher(Teacher teacher) { teacherDao.insert(teacher); //throw new RuntimeException("运行异常"); //用来演示事务回滚 } }
package cn.lyy.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import cn.lyy.model.Teacher; @Repository public class TeacherDao { @Autowired private JdbcTemplate jdbcTemplate; public void insert(Teacher teacher) { final String sql = "insert into teacher values(" + teacher.getId() + ",'" + teacher.getName() + "','" + teacher.getEmail() + "')"; jdbcTemplate.execute(sql); } }
package cn.lyy.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import cn.lyy.model.Teacher; import cn.lyy.service.TeacherService; @Controller @RequestMapping public class TeacherController { @Autowired private TeacherService teacherService; @RequestMapping(value = "/addteacher.do") public void addTeacher() { Teacher teacher = new Teacher(); teacher.setId(3); teacher.setName("lyysssss"); teacher.setEmail("[email protected]"); teacherService.addTeacher(teacher); } }
<?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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" /> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> </beans>
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <import resource="classpath:applicationContext-dao.xml" /> <context:component-scan base-package="cn.lyy.dao" /> <context:component-scan base-package="cn.lyy.model" /> <context:component-scan base-package="cn.lyy.service" /> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="add*" isolation="READ_COMMITTED" propagation="REQUIRED" rollback-for="java.lang.RuntimeException" /> <tx:method name="update*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* cn.lyy.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> </aop:config> </beans>
#postgre jdbc.driverClassName=org.postgresql.Driver jdbc.url=jdbc:postgresql:test jdbc.username=lyy jdbc.password=lyy
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="cn.lyy.controller" /> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/" /> <property name="suffix" value=".jsp"></property> </bean> </beans>
其他的就省略了。
总的来说,对事务有了一个大概的了解。接下里就应该了解一下事务的隔离级别,传播途径等内容了!