1、介绍
Spring封装了事务管理代码
(1)事务管理对象
因为在不同平台,操作事务的代码各不相同,spring提供了一个接口。
PlatformTransactionManager 接口
|---DataSourceTransactionManager
|---HibernateTransitionmanager
注意:在spring中玩事务管理.最为核心的对象就是TransactionManager对象
(2)Spring管理事务的属性介绍
A、事务的隔离级别
1 读未提交
2 读已提交
4 可重复读
8 串行化
B、是否只读
true 只读
false 可操作
C、事务的传播行为
决定业务方法之间调用,事务该如何处理
PROPAGATION_REQUIRED:支持当前事务,如果不存在,就新建一个。(默认)
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务。
PROPAGATION_MANDATORY:支持当前事务,如果不存在,就抛异常。
PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务。
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务。
PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛异常。
PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行。
2、Spring事务管理方式
测试准备:
数据库:
Account类:
public class Account {
private String name;
private int money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
AcountDaoImpl:
public class AcountDaoImpl extends JdbcDaoSupport implements AcountDao {
@Override
public void add(String name, Integer money) {
String sql = "update account set money=money+? where name=?";
super.getJdbcTemplate().update(sql, money,name);
}
@Override
public void subtract(String name, Integer money) {
String sql = "update account set money=money-? where name=?";
super.getJdbcTemplate().update(sql, money,name);
}
}
(1)编码式
A、application.xml中配置
<!-- 事务管理核心器,封装了所有事务操作,依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务模板对象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
B、service中调用模板
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AcountService {
@Resource(name="acountDao")
private AcountDao ad;
@Resource(name="transactionTemplate")
private TransactionTemplate tt;
@Test
public void test() {
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) {
ad.subtract("rose", 100);
ad.add("tom", 100);
}
});
}
}
(2)xml配置(aop)
A、导包
4+2+aop+aspect+aop联盟+weaver织入包
B、导入新约束(tx:事务约束)
C、配置通知+将通知织入目标
<!-- 事务管理核心器,封装了所有事务操作,依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer2" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 将事务通知织入目标 -->
<aop:config>
<aop:pointcut expression="execution(* club.ityuchao.service.AcountService2.transfer2(..))" id="txPc"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>
D、测试
public class AcountService2 {
private AcountDao ad;
public void transfer2(String from,String to,Integer money) {
ad.subtract(from, money);
int i = 1/0;
ad.add(to, money);
}
public AcountDao getAd() {
return ad;
}
public void setAd(AcountDao ad) {
this.ad = ad;
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:club/ityuchao/service/applicationContext.xml")
public class Demo {
@Resource(name="acountService2")
private AcountService2 as;
@Test
public void test() {
as.transfer2("rose", "tom", 100);
}
}
(3)注解配置(aop)
A、导包
B、导入约束(tx)
C、开启注解管理事务
<!-- 事务管理核心器,封装了所有事务操作,依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用注解配置事务aop -->
<tx:annotation-driven/>
D、使用注解
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AcountService3 {
private AcountDao ad;
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
public void transfer2(String from,String to,Integer money) {
ad.subtract(from, money);
int i = 1/0;
ad.add(to, money);
}
public AcountDao getAd() {
return ad;
}
public void setAd(AcountDao ad) {
this.ad = ad;
}
}
可以再类上写注解,也可以在方法上写注解