Spring基于注解的声明式事务控制
### 注解配置声明式事务控制解析
①使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。
②注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。
③使用在方法上,不同的方法可以采用不同的事务参数配置。
④Xml配置文件中要开启事务的注解驱动<tx:annotation-driven />
### 知识要点
**注解声明式事务控制的配置要点**
- 平台事务管理器配置(xml方式)
- 事务通知的配置(@Transactional注解配置)
- 事务注解驱动的配置 <tx:annotation-driven/>
配置文件
<?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"
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.code_g"/>
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- <bean id="accountDao" class="com.code_g.dao.Impl.AccountDaoImpl">-->
<!-- <property name="jdbcTemplate" ref="jdbcTemplate"/>-->
<!-- </bean>-->
<!-- <bean id="accountService" class="com.code_g.service.Impl.AccountServiceImpl">-->
<!-- <property name="accountDao" ref="accountDao"/>-->
<!-- </bean>-->
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--<!– 事务通知–>-->
<!-- <tx:advice id="myAdvice" transaction-manager="transactionManager">-->
<!-- <tx:attributes>-->
<!-- <tx:method name="*"/>-->
<!-- </tx:attributes>-->
<!-- </tx:advice>-->
<!--<!–事务织入–>-->
<!-- <aop:config>-->
<!-- <aop:advisor advice-ref="myAdvice" pointcut="execution(* com.code_g.service.impl.*.*(..))"/>-->
<!-- </aop:config>-->
</beans>
dao层实现类
package com.code_g.dao.Impl;
import com.code_g.dao.AccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {
@Resource(name = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Override
public void out(String outMan, double money) {
jdbcTemplate.update("update account set money = money - ? where name = ?",money,outMan);
}
@Override
public void in(String inMan, double money) {
jdbcTemplate.update("update account set money = money + ? where name = ?",money,inMan);
}
}
service层实现类
package com.code_g.service.Impl;
import com.code_g.dao.AccountDao;
import com.code_g.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Resource(name = "accountDao")
private AccountDao accountDao;
@Override
@Transactional //事务通知注解
public void transfer(String outMan, String inMan, double money) {
accountDao.out(outMan,money);
// int i = 1/0;
accountDao.in(inMan,money);
}
}
测试类
package com.code_g.test;
import com.code_g.domain.Account;
import com.code_g.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TxTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private AccountService accountService;
@Test
public void test1(){
Account query = jdbcTemplate.queryForObject("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), "郭奉孝");
System.out.println(query);
}
@Test
public void test2(){
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// AccountService accountService = (AccountService) applicationContext.getBean("accountService");
accountService.transfer("郭奉孝","曹操",500);
}
}