1.Spring有哪些事务?
(1)spring提供了编程式事务支持 TransactionTemplate;
(2)也提供了声明式事务支持 底层采用AOP实现的事务通知bean;
(3)也有注解形式的 @Transactional
2.Spring中怎么使用事务?
(1)编程式事务 在DAO中通过TransactionTemplate模板类封装事务的管理过程
(2)声明式事务(AOP配置事务通知bean):底层采用AOP思想实现,将事务的管理过程(包括事务对象的创建,提交和回滚作)封装在一个事务通知bean中,然后通过配置AOP切入点的方式来描述需要将事务通知bean所提供的事务管理服务引用给哪些核心对象/方法。
配置方式依赖于AOP的配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="underclassmen" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="" transaction-manager="transactionManager"(指向一个事务管理器)>
<tx:attributes> 为不同的方式设置不同的事务属性
<tx:method name="表达式匹配方法" 四个属性...rollback-for="监听到什么异常回滚事务"/>
<tx:method name="add*" isolation="READ_COMMITTED" propagation="REQUIRED" rollback-for="java.lang.RuntimeException"/>
<tx:method name="*" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="perform" expression="execution(* com.hofon.serviceImpl.XXXServiceImpl.*(..))"(表达式指向需要引用事务的方法列表)/>
<aop:advisor advice-ref="transaction" pointcut-ref="perform"/>()
</aop:config>
上述execution(* com.hofon.serviceImpl.XXXServiceImpl.*(..))表达式表示切入点为该类中的任何方法。所以当XXXServiceImpl类中方法调用时就会进行事务管理
,并且当抛出RuntimeException或者Exception时(看具体方法名),自动进行回滚操作。
,并且当抛出RuntimeException或者Exception时(看具体方法名),自动进行回滚操作。
或者(Hibernate)
<?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: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-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- 配置SessionFactory -->
<bean id="sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name="configLocation" value= "classpath:hibernate.cfg.xml" />
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionMgr" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" >
<property name="sessionFactory" >
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 配置事务传播特性 -->
<tx:advice id="txAdvice" transaction-manager= "transactionMgr" >
<tx:attributes>
<tx:method name="add*" propagation= "REQUIRED" />
<tx:method name="del*" propagation= "REQUIRED" />
<tx:method name="update*" propagation= "REQUIRED" />
<tx:method name="*" read-only= "true" />
</tx:attributes>
</tx:advice>
<!-- 那些类使用事务 -->
<aop:config>
<aop:pointcut id="point-cut" expression= "execution(* com.hofon.manager.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref= "point-cut" />
</aop:config>
</beans>
声明式事务的特性 : 不需要在核心代码中编写事务的管理过程,以此将核心代码与事务管理服务动态分离。
声明式事务回滚的方式 : 默认产生运行时异常时回滚,可设置(如Exception)
(3)使用@Transactional注解来实现声明式事务
①引入<tx:>命名空间 ,在spring的配置文件中修改, 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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
②配置事务管理器transactional和开始事务的注解支持
<!-- 配置spring的PlatformTransactionManager,名字为默认值 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启事务控制的注解支持 -->
<!--用@Transactional 注解替代tx/aop命名空间 来实现 Spring声明式事务管理-->
<!--在service类上使用注解@Transactional -->
<tx:annotation-driven transaction-manager="transactionManager"/></span></span>
③
在接口或类的声明处 ,写一个@Transactional. 要是只在接口上写, 接口的实现类就会继承下来.在
接口的实现类的具体方法上,还可以覆盖类声明处的设置.
当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该注解来覆盖类级别的定义。
//在service类上的注解
@Transactional
@Service
@Scope("prototype")
public class NewsServiceImpl implements NewsService {
@Autowired
private NewsDao nd;
@Override
@Transactional(readOnly=true) //为方法增加事务处理特性
public List showAllNews() {
List<News> allNewList = nd.showAllNews();
return allNewList;
}
}
1、检查你方法是不是public的
2、 你的异常类型是不是unchecked异常 ,默认运行时异常RuntimeException才回滚
要想所有异常都回滚,注解上面写明异常类型即可
2、 你的异常类型是不是unchecked异常 ,默认运行时异常RuntimeException才回滚
要想所有异常都回滚,注解上面写明异常类型即可
@Transactional(rollbackFor=Exception.class)
类似的还有norollbackFor,自定义不回滚的异常
3、数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的
4、是否开启了对注解的解析
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
5、spring是否扫描到你这个包,如下是扫描到com.hofon下面的包,必须是spring里配置的bean才起作用?
<context:component-scan base-package="com.hofon" ><context:component-scan>
类似的还有norollbackFor,自定义不回滚的异常
3、数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的
4、是否开启了对注解的解析
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
5、spring是否扫描到你这个包,如下是扫描到com.hofon下面的包,必须是spring里配置的bean才起作用?
<context:component-scan base-package="com.hofon" ><context:component-scan>