Spring声明式事务xml实现

113 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

xml方式实现

①配置事务管理器
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">       
    <property name="dataSource" ref="dataSource"/>   
</bean>
②配置事务切面
 	<!--定义事务管理的通知类-->   
<tx:advice transaction-manager="txManager" id="txAdvice">     
    <tx:attributes>           
        <tx:method name="trans*"/>       
    </tx:attributes>    
</tx:advice>

<aop:config>       
    <aop:pointcut id="pt" expression="execution(* com.springstudy.service..*.*(..))"></aop:pointcut>        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt">
    </aop:advisor>   
    </aop:config>

注意,因为声明式事务底层是通过AOP实现的,所以最好把AOP相关依赖都加上。

       <dependency>   
       <groupId>org.aspectj</groupId>      
       <artifactId>aspectjweaver</artifactId>    
       <version>1.9.6</version>    
       </dependency>

属性配置

事务传播行为propagation

​ 当事务方法嵌套调用时,需要控制是否开启新事务,可以使用事务传播行为来控制。

测试案例:

@Servicepublic
class TestServiceImpl {    
    @Autowired    
    AccountService accountService;    
    @Transactional    
    public void test(){        
        accountService.transfer(1,2,10D);       
        accountService.log();    }}
public class AccountServiceImpl implements AccountService {	
    //...省略其他不相关代码  
    @Transactional    
    public void log() {        
        System.out.println("打印日志");       
        int i = 1/0;  如果日志里面报错,转账也就回滚
        }}
属性值行为
REQUIRED(必须要有)外层方法有事务,内层方法就加入。外层没有,内层就新建
REQUIRES_NEW(必须要有新事务)外层方法有事务,内层方法新建。外层没有,内层也新建
SUPPORTS(支持有)外层方法有事务,内层方法就加入。外层没有,内层就也没有
NOT_SUPPORTED(支持没有)外层方法有事务,内层方法没有。外层没有,内层也没有
MANDATORY(强制要求外层有)外层方法有事务,内层方法加入。外层没有。内层就报错
NEVER(绝不允许有)外层方法有事务,内层方法就报错。外层没有。内层就也没有

例如:

    @Transactional(propagation = Propagation.REQUIRES_NEW)   
public void transfer(Integer outId, Integer inId, Double money) {
    //增加    
    accoutDao.updateMoney(inId,money);      
    //减少    
    accoutDao.updateMoney(outId,-money);   
    }

3.3.2 隔离级别isolation

Isolation.DEFAULT 使用数据库默认隔离级别

Isolation.READ_UNCOMMITTED

Isolation.READ_COMMITTED

Isolation.REPEATABLE_READ

Isolation.SERIALIZABLE

   @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED) 
public void transfer(Integer outId, Integer inId, Double money) {    
       //增加    
       accoutDao.updateMoney(inId,money);        
    //减少      
    accoutDao.updateMoney(outId,-money);    }

3.3.3 只读readOnly

​ 如果事务中的操作都是读操作,没涉及到对数据的写操作可以设置readOnly为true。这样可以提高效率。

    @Transactional(readOnly = true) 
    public void log() {     
    System.out.println("打印日志");   
    int i = 1/0; 
    }