Spring对事务管理的支持
Spring允许通过声明方式,在IOC配置中指定事务的边界和事务属性,Spring自动在指定的事务边界上应用事务属性。
在Spring的事务管理SPIService Provider Interface
的抽象层主要包含3个接口:PlatfromTransactonManager
,TransactionDefiniton
,TransactionStatus
TransactionDefiniton:用于描述事务的隔离级别、超时时间、是否为只读事务和事务传播规则等控制事务具体行为的事务属性。
-
事务隔离:当前事务和其他事务的隔离程度。
ISOLATION_READ_UNCOMMITTED
,ISOLATION_READ_COMMITTED
,ISOLATION_REPEATABLE_READ
,ISOLATION_SERIALIZABLE
,ISOLATION_DEFAULT
-
事务超时:事务在超时前能运行多久,超过时间后,事务将被回滚
-
只读状态:只读事务不修改任何数据,资源事务管理者可以针对可读事务应用一些优化措施,提高运行性能。
-
事务传播:通常在一个事务中所执行的所有代码都会运行于同一事务上下文中,但是当我们调用一个基于Spring的
Service
接口方法的时候,它将运行于Spring管理的事务环境中,Service
接口方法可能会在内部调用其他的Service
接口方法以共同完成一个完整的业务操作,因此就会产生服务接口方法嵌套调用的情况,Spring通过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中。事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前存在事务,就加入事务中;没有就新建事务 PROPAGATION_SUPPORTS 支持当前事务,如果没有事务就以非事务方式执行 PROPAGATION_MANDATORY 使用当前事务,如果没有事务,就抛出异常 PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,则把当前事务挂起 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,则把当前事务挂起 PROPAGATION_NEVER 以非事务方式执行,入股当前存在事务,则抛出异常 PROPAGATION_NEXTED 如果当前存在事务,则在嵌套事务执行;没有,则执行_REQUIRED
PlatfromTransactonManager:根据TransactionDefiniton
提供的事务属性配置信息创建事务,并用TransactionStatus
描述这个事务的状态。
入门程序
开发环境:DAO
public interface AccountDao {
public void outMoney(String out, double money);
public void inMoney(String in, double money);
}
/******************* JDBC模板类 *********************************/
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
//扣钱
@Override
public void outMoney(String out, double money) {
this.getJdbcTemplate().update(
"UPDATE t_account SET money = money - ? WHERE name = ?",money,out);
}
//加钱
@Override
public void inMoney(String in, double money) {
this.getJdbcTemplate().update(
"UPDATE t_account SET money = money + ? WHERE name = ?",money,in);
}
}
开发环境:Service
public interface AccountService {
public void pay(String out, String in, double money);
}
/***********************************************************/
//注解方式开发需添加:@Transactional 表明类中所有的方法都有事务
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void pay(String out, String in, double money) {
//先扣钱
accountDao.outMoney(out,money);
//再加钱
accountDao.inMoney(in, money);
}
}
配置声明式事务
配置Spring内置连接池
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_jdbc"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
配置平台事务管理器
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
配置DAO和Service
<bean id="accountService" class="Tx.Xml.Service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="Tx.Xml.Dao.AccountDaoImpl">
<!-- 注入连接池,可去掉JDBC模板类的配置 -->
<property name="dataSource" ref="dataSource"/>
</bean>
XML
配置增强,引入平台事务管理器
<tx:advice id="myAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="pay" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
配置AOP
<aop:config>
<aop:advisor advice-ref="myAdvice" pointcut="execution(public * Tx.Xml.Service.AccountServiceImpl.pay(..))"/>
</aop:config>
注解@Transaction
开启事务注解
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test {
@Resource(name = "accountService")
private AccountService accountService;
@org.junit.Test
public void testAccountDao(){
accountService.pay("Jack","Gong",50);
}
}
下一篇:Spring学习笔记[8]之Cache[缓存] https://blog.csdn.net/Rabbit_Judy/article/details/81842705