Spring管理事务
PlatformTransactionManager 帮助我们管理任意平台的事务。
Jdbc DataSourceTransactionManager
Hibernate HibernateTransactionManager
…… ……TransactionManager
事务:(4大特性)
(1).一致性 (2).原子性
(3).持久性 (4).隔离性
事务安全:
事务线程安全:脏读 不可重复读 幻读 读未提交
隔离级别:1 2 4(读已提交) 8
所有事务的操作有三步:
开启事务
提交事务
回滚事务
Spring管理事务 利用的是spring aop思维,将事务的操作织入到目标对象中。
Spring管理事务的属性:
隔离级别 是否只读 事物的传播行为(7种)
Spring管理事务的三种方式
(1)、代码式
1、配置事务管理对象
2、配置事务管理的模板
3、在service中注入模板对象,然后调用execute方法。
package cn.hd.spring_transaction.impl;
import cn.hd.spring_transaction.UserDao;
import cn.hd.spring_transaction.UserService;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
@Resource(name ="transactionTemplate")
private TransactionTemplate tt;
public void setTt(TransactionTemplatett) {
this.tt = tt;
}
@Override
public void transform(Integer form,Integer to, Integer money) {
/*TransactionCallbackWithoutResult()没有任何返回值的回调函数*/
tt.execute(newTransactionCallbackWithoutResult() {
@Override
protected voiddoInTransactionWithoutResult(TransactionStatus transactionStatus) {
userDao.increase(to,money);
int i = 1/0;
userDao.decrease(form,money);
}
});
}
}
(2)、xml配置
1、有一个事务管理对象
<bean name="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource" ref="dataSource"></property>
</bean>
2、配置事务的通知
标签名 tx:advice id给当前的事务起个标记
Transact….. 配置刚刚的事务管理对象
配置参数:method name 可以是具体某个方法(方法名) 比较麻烦,可以使用通配符的方式去配置
add* delete* update* get* persist* remove* modify* find*
要求:你的service的命名必须规范。
isolation:隔离级别使用默认即可(4)default
propagation: 事务传播行为 required
read-only:是否只读 如果查找 true 否则为false
<!--配置事务通知-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<!--事务的属性-->
<tx:attributes>
<!--给那个方法添加事务;隔离:默认(级别4);传播行为:如果事物存在运行,不存在新建;是否只读-->
<tx:methodname="transform" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
<tx:method name="get*"isolation="DEFAULT" propagation="REQUIRED"read-only="true"/>
<tx:methodname="add*" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
<tx:methodname="update*" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
<tx:methodname="delete*" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
<tx:methodname="find*" isolation="DEFAULT"propagation="REQUIRED" read-only="true"/>
<tx:methodname="persist*" isolation="DEFAULT" propagation="REQUIRED"read-only="false"/>
<tx:methodname="modify*" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
<tx:methodname="remove*" isolation="DEFAULT"propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
3、将通知织入到目标对象
<!--将通知织入到目标对象-->
<aop:config>
<!--切点-->
<aop:pointcut id="txPc"expression="execution(*cn.hd.spring_transaction..impl.*ServiceImpl.*(..))"></aop:pointcut>
<!--切面-->
<aop:advisoradvice-ref="myAdvice" pointcut-ref="txPc"></aop:advisor>
</aop:config>
配置切面不再使用aop:aspect,而是aop:advisor
(3)、注解配置
1、开启注释模式
<!--开启注解模式-->
<tx:annotation-driven></tx:annotation-driven>
2、在想设置的事务的地方,加上注解
@Transactional(isolation= Isolation.DEFAULT,propagation =
Propagation.REQUIRED,readOnly = false)
可以有两个位置:
1、类上面,该类中所有的方法都会使用以上的参数事务。
2、方法名上面,该方法使用参数中的事务
如果两个都设置以方法名上面的事务为准。