Spring事务
Posted Claricre
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring事务相关的知识,希望对你有一定的参考价值。
事务:一系列的动作,被当成一个单独的工作单元,要么都完成,要么全部不起作用。 事务的四个属性:ACID 原子性,一致性,隔离性,持久性 之前的事务处理:JDBC与Hibernate中的事务处理——与try...catch...finally...一起用。 Spring中的事务处理:编程式,声明式。 Spring从事务管理的API中抽象出一套独立事务机制。事务管理代码能独立于特点的具体技术。 一、Spring的声明性事务。 准备工作:配置数据源对象。 首先,配置事务管理器。 DataSourceTransactionManager类 dataSource属性注入 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> 然后,在配置文件中启用事务注解 把tx命名空间加进来。 <tx:annotation-driven transaction-manager=""transactionManager"> 最后,添加事务注解。在使用的方法上添加这个注解。 @Transactional
1.使用注解声明事物
<?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" default-autowire="byName" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 自动扫描 --> <context:component-scan base-package="com.itnba.maya.daoImpl,com.itnba.maya.serviceImpl"></context:component-scan> <!-- 读取数据库连接文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 生成连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成JdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务管理器 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 启动事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
注解演示:
package com.dao; public interface IInfoDao { public void delete(String code); }
package com.dao; public interface IWorkDao { public void deleteByInfoCode(String code); }
package com.daoimpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.dao.IInfoDao; @Repository public class InfoDao implements IInfoDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void delete(String code) { int i = 5/0; String sql="delete from info where code=?"; jdbcTemplate.update(sql, code); } }
package com.daoimpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.dao.IWorkDao; @Repository public class WorkDao implements IWorkDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public void deleteByInfoCode(String code) { String sql="delete from work where infocode=?"; jdbcTemplate.update(sql,code); } }
package com.service; public interface IInfoservice { public void delete(String code); }
package com.serviceimpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.daoimpl.InfoDao; import com.daoimpl.WorkDao; import com.service.IInfoservice; @Service public class InfoService implements IInfoservice { @Autowired private InfoDao infodao; @Autowired private WorkDao workdao; @Transactional @Override public void delete(String code) { workdao.deleteByInfoCode(code); infodao.delete(code); } }
package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.dao.IInfoDao; import com.dao.IWorkDao; import com.service.IInfoservice; import com.serviceimpl.InfoService; public class Test { private static ApplicationContext context = null; private static IInfoDao infodao= null; private static IWorkDao workdao= null; private static IInfoservice infoService = null; static{ context= new ClassPathXmlApplicationContext("beans.xml"); infodao = (IInfoDao)context.getBean("infoDao"); workdao = (IWorkDao)context.getBean("workDao"); infoService = (IInfoservice)context.getBean("infoService"); } public static void main(String[] args) { infoService.delete("p004"); } public static void main1111(String[] args) { workdao.deleteByInfoCode("p004"); infodao.delete("p004"); } }
从上面几个类中可以观察出来,infodao里面有一个5/0是肯定要报异常的,那么这时候如果没有事务,不添加注解,无论是跑main还是main1111,因为都是先执行workdao再执行infodao的delete,所以work表里面的关于p004的内容都删除了,然后infodao里面的内容因为有异常所以并未删除。但是我们想要的是如果有异常抛出,则所有内容都不删除,此时就需要通过添加注解来添加事务。如果有事务,则会有异常时回滚数据,并不会删除了。
二、事务的传播行为
一个事务方法调用另一个事务方法时,如何进行事务控制。是做为外部事务的整体控制?还是做为内部事务的部分控制? 在@Transactional注解中,使用propagation属性指导事务的传播行为。 required -- 有事务就行(事务默认传播行为) @Transactional(propagation=Propagation.REQUIRED) required new -- 使用自己的事务,外面调用的方法的事务被挂起。 @Transactional(propagation=Propagation.REQUIRES_NEW)
还以上面题目作为示例,(如果我在service层中加上事物)
@Service public class InfoService implements IInfoService { @Autowired//ByName自动装配 private IWorkDao workDao; @Autowired private IInfoDao infoDao; //@Transactional(propagation=Propagation.REQUIRES_NEW)//使用自己的事务,TestAll中的事物将不起作用。 @Transactional(propagation=Propagation.REQUIRED)//默认事物传播方式 @Override public void delete(String code) { workDao.deleteByInfoCode(code); infoDao.delete(code); } }
**************************************************************************************************************
通过XML方式来声明事物
配置数据源对象 用<bean>实例化各个业务对象。 1.配置事务管理器。 <bean id="transactionManager" class="org.springframework.jdbc.datasourceManager"> <property name="datasource" ref="datasource"></property> </bean> 2.配置事务属性 <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="方法名" propagation="REQUIRES_NEW"/> <!--新开事务--> <tx:method name="*"/> <!--使用原有事务--> </tx:attributes> </tx:advice> 3.配置事务切入点,注入事务属性 <aop:config> <aop:pointcut expression="execution(.......)" id="txPointCut"/> <aop:advisor advice-ref="txtAdvice" pointcut-ref="txtPointCut"/> </aop:config>
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" default-autowire="byName" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 读取数据库连接文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 生成连接池 --> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"> <property name="driverClass" value="${driverClass}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> </bean> <!-- 生成JdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 属性注入 --> <bean class="com.itnba.maya.daoImpl.InfoDao" id="infoDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean class="com.itnba.maya.daoImpl.WorkDao" id="workDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean class="com.itnba.maya.serviceImpl.InfoService" id="infoService"> <property name="workDao" ref="workDao"></property> <property name="infoDao" ref="infoDao"></property> </bean> <!-- 配置事务管理器 --> <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- *代表对所有的事物方法 --> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- Spring的事务声明是基于AOP面向切面实现的(不要忘记倒入aspectjweaver的jar包),切面Spring已经定义好了,我们只需要定义切点就可以 --> <aop:config> <!-- 定义切点(pointcut),所有包中的所有类中的所有方法都加上事务 --> <aop:pointcut expression="execution(* com.itnba.maya..*.*(..))" id="pointCut"/> <!-- 将切点与事务联系起来 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/> </aop:config> </beans>
package com.daoimpl;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;
import com.dao.IInfoDao;@Repositorypublic class InfoDao implements IInfoDao {@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic void delete(String code) {int i = 5/0;String sql="delete from info where code=?";jdbcTemplate.update(sql, code);}
}
以上是关于Spring事务的主要内容,如果未能解决你的问题,请参考以下文章
使用 OnItemClickListener 列出视图片段到片段事务