事务的四个特性:A原子性 D持久性 I隔离性 C一致性
隔离级别:Read-Uncommited(读未提交的一行数据:脏读、不可重复读、幻读)
Read-Commited
(读已提交的一行数据:不可重复读、幻读)
Read-Repeatable
(可重复读已提交的一行数据:幻读)----MySQL默认Default
Serialization
(序列化)
对于Dao层(持久化)的操作,高并发时,容易造成数据出错(银行转账:一方扣款,然后出异常(不回滚),另一方没办法收款----总金额减少)
事务管理出现在------Service层
Spring对事务管理的支持-----DataSourceTransactionManager(JDBC,Mybatis)、HibernateTransactionManager(Hibernate)
使用事务管理器
1.编程式引入事务管理:
一、AplicationContext注入依赖---引入事务管理模板----Service类引入事务管理模板---Service类中引入事务:
<bean id="transactionManager" Class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/><!-- c3p0连接池的bean -->
</bean>
<!-- 配置事务管理模板:Spring为简化事务管理而提供的类 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
- <!-- Service类 -->
<bean id="XXXService" class="xxxServiceImpl">
<property name="xxxDao" ref="xxxDao">
<!-- 引入事务管理模板 -->
<property name="transactionTemplate" ref="transactionTemplate">
</bean>
二、ServiceImpl类中的方法引入事务:
//注入事务模板
private TransacitonTemplate transactionTemplate;
- public void setTransactionTemplate(TransactionTemplate transactionTemplate){
- this.transactionTemplate = transactionTemplate;
- }
//需要引入事务的方法
public void transfer(final String out,final String in,final Double money){
transactionTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus ts){
//里面写要执行事务的操作
//若成功则成功,若失败则回滚
}
})
}
三、Test.java中注入XXXService
测试调用事务方法
//注入代理类
@Resource(name="xxxService")
private XXXService xxxService;
//测试方法中:
xxxService.transfer("aaa","bbb",200);
2.声明式事务管理一(基于transactionProxyFactoryBean的方式)---AOP思想(引入AOP的jar包:1.spring-aop 2.com.springsource.org.aopalliance)
一、ApplictionContext中注入transactionManager----注入ServiceImpl的代理类xxxServiceProxy(注入事务目标对象、注入事务管理器、注入事务隔离级别)
<bean id="transactionManager" Class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/><!-- c3p0连接池的bean -->
</bean>
<!-- 配置Service层代理类 -->
<bean id = "xxxServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--配置目标对象 -->
<property name="target" ref="xxxService"/>
<!--注入事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 注入事务隔离级别、属性 -->
<property name="TransactionAttributes">
<props>
<!-- 格式:key=”insert*“即以insert开头的方法
* PROPAGATION : 事务传播行为
* ISOLATION : 事务的隔离级别
* readOnly : 只读(不可修改)
* -Exception : 发生哪些异常后回滚事务再提交
* +Exception : 发生哪些异常后不回滚事务直接提交
-->
<prop key="transfer*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
二、XXXserviceImpl.java中写事务方法
//需要引入事务的方法
public void transfer(String out,String in,Double money){
//里面写要执行事务的操作
//若成功则成功,若失败则回滚
}
三、Test.java中注入
xxxServiceProxy代理bean测试调用事务方法
//注入代理类
@Resource(name="xxxServiceProxy")
private XXXService xxxService;
//测试方法中:
xxxService.transfer("aaa","bbb",200);
3.声明式事务管理二(基于AspectJ的XML方式)---设置切面---》放入事务管理
引入aspectj和spring-aspects的jar包,ApplicationContext引入aop、tx命名空间
<!-- 配置事务管理 -->
<bean id="transactionManager" Class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/><!-- c3p0连接池的bean -->
</bean>
<!-- 配置事务的通知:(事务的增强) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- prpagation:
事务传播行为isolation:
事务的隔离级别read-only:
只读(不可修改)rollback-for:
发生哪些异常后回滚事务再提交no-rollback-for:
发生哪些异常后不回滚事务直接提交- timeout:过期
-->
<tx:method name="transfer" prpagation="REQUIRED"/isolation="DEFAULT" read-only="false" rollback-for="" timeout="-1" no-rollback-for=""/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com....XXXService+.*(..))" id="pointcut1"/> id="pointcut1">
<!-- 配置切面 -->
<aop:advisor advice-ref="txAdvice" piontcut-ref="pointcut1"/>
</aop:config>
</bean>
二、XXXserviceImpl.java中写事务方法
//需要引入事务的方法
public void transfer(String out,String in,Double money){
//里面写要执行事务的操作
//若成功则成功,若失败则回滚
}
三、Test.java中注入XXXService
测试调用事务方法
//注入代理类
@Resource(name="xxxService")
private XXXService xxxService;
//测试方法中:
xxxService.transfer("aaa","bbb",200);
3.声明式事务管理三(基于注解的方式)
一、ApplicationContext配置事务管理-----开启注解事务驱动
<!-- 配置事务管理 -->
<bean id="transactionManager" Class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/><!-- c3p0连接池的bean -->
</bean>
<!-- 开启注解事务驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</bean>
二、
XXXserviceImpl.java类中加上@Transactional注解,写事务方法
/**
propagation
isolation
rollback
readOnly
noRollbackFor
*/
@Transactional(propagation="" isolation="" rollbackFor="" readOnly="" noRollbackFor="")
public class XXXServiceImpl implement XXXService{
.......
//需要引入事务的方法
public void transfer(String out,String in,Double money){
//里面写要执行事务的操作
//若成功则成功,若失败则回滚
}
}
三、Test.java中注入XXXService
测试调用事务方法
//注入代理类
@Resource(name="xxxService")
private XXXService xxxService;
//测试方法中:
xxxService.transfer("aaa","bbb",200);