Spring事物管理

事物管理

spring封装了事务管理的代码,包括打开事物,提交事物,回滚事物.

因为在不同的平台操作事务的代码各不相同,因此spring提供了一个接口PlatformTransactionManager接口,在不同的平台下提供不同的实现类

注意:在Spring中玩事务管理,最为核心的对象就是TransactionManager

Spring管理事务的属性介绍

  • 选择事务的隔离级别
  • 选择是否只读
  • 事务的传播行为:决定业务方法之间调用,事务应该如何处理

Transaction模板(了解)

spring管理事务的方式管理事物的方式分为三种

首先,这三种方法的共有步骤就是将核心的事物管理器配置到Spring容器中,如下

<!-- 事务核心管理器,封装了所有的事务操作,依赖于连接池 -->
<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>

以转账的例子为例,首先在Dao层创建AccountDaoImpl类,实现转账的方法

AccountDao:

public interface AccountDao {
	 void increaseMoney(Integer id,Double money);
	 void decreaseMoney(Integer id,Double money);
}

 AccountDaoImpl:

import org.springframework.jdbc.core.support.JdbcDaoSupport;

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
	@Override
	public void increaseMoney(Integer id, Double money) {	
		getJdbcTemplate().update("update t_account set money = money+? where id =?", money,id);
	}

	@Override
	public void decreaseMoney(Integer id, Double money) {
		getJdbcTemplate().update("update t_account set money = money-? where id =?", money,id);
	}
}

 当然,在applicationContext.xml中先配置好连接池对象

<!-- 1、连接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

<!-- 2、Dao -->
<bean name="accountDao" class="com.tz.dao.AccountDaoImpl">
    <property name="dataSource" ref="dataSource"></property>
</bean>
View Code

编码式(了解)

使用编码式首先要给Service层注入一个TransactionTemplate对象

AccountService:

public interface AccountService {
    void transfer(Integer from,Integer to, Double money);
}
View Code

AccountServiceImpl:

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.tz.dao.AccountDao;

public class AccountServiceImpl implements AccountService {

    private AccountDao ad;
    private TransactionTemplate tt;            

    
//    @Override
    public void transfer(final Integer from,final Integer to,final Double money) {
        
        tt.execute(new TransactionCallbackWithoutResult() {

            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                                // 在这里面实现事物逻辑
                ad.decreaseMoney(from, money);
                int i = 1/0;
                ad.increaseMoney(to, money);

            }
        });
    }
        


    public void setAd(AccountDao ad) {
        this.ad = ad;
    }


    public void setTt(TransactionTemplate tt) {
        this.tt = tt;
    }
    
}
View Code

在上面的代码中 doInTransactionWithoutResult() 已经帮我们完成了开始事物,关闭事物,回滚事物的操作,我们只要专心进行操作即可

另:上面的代码只是观光代码,一般不会用在生产中

xml配置(Aop重点)

使用xml配置首先需要在配置文件中配置事物通知跟织入,当然,在这之前要先导入tx约束跟aop约束

<!-- 配置事务通知 -->
<tx:advice id="txAdvisor" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
        <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
        <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
        <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    </tx:attributes>

</tx:advice>

<!-- 配置织入 -->
<aop:config>
    <aop:pointcut expression="execution(* com.tz.service.*ServiceImpl.*(..))" id="txPc"/>
    <!-- 配置切面 -->
        <aop:advisor advice-ref="txAdvisor" pointcut-ref="txPc"/>
</aop:config>
View Code

 上面的参数说明:

  • isolation:隔离级别
  • propagation:传播行为
  • read-only:是否只读

上面的配置完成后就会自动去匹配Service里面的方法,不必在Service中再做什么操作

import com.tz.dao.AccountDao;

public class AccountServiceImpl implements AccountService {

	private AccountDao ad;
	
	@Override
	public void transfer(final Integer from,final Integer to,final Double money) {
            ad.decreaseMoney(from, money);	
	    int i = 1/0;
	    ad.increaseMoney(to, money);
	}
}

注解配置(Aop重点)

使用注解配置的道理跟xml配置差不多

使用注解只需要在配置文件中配置里面开启一下注解即可

<!-- 开启注解 -->
<tx:annotation-driver transaction-manager="transactionManager" />

 然后要对哪个方法使用事物模板就在那个方法上面配置上注解,或者在类上面配置上注解对整个类的方法都有效,如果该类中有极个别的方法配置的参数不同,只需要在对应的方法上配置上注解即可,然后类的注解便不会对该方法有效

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.transaction.support.TransactionTemplate;

import com.tz.dao.AccountDao;

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {
	private AccountDao ad;
	
	@Override
        @Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
	public void transfer(final Integer from,final Integer to,final Double money) {
		ad.decreaseMoney(from, money);
		int i = 1/0;
		ad.increaseMoney(to, money);
	}
}

 如上配置即可

 

posted @ 2018-08-07 17:53  Jin同学  阅读(134)  评论(0)    收藏  举报