Spring之事务管理

什么是事务?

事务是指一组逻辑上的操作,这些操作要么都失败,要么都成功。

事务的特性

  • 原子性:事务中所有的操作,要么都成功,要么都失败。
  • 隔离性:在多个用户访问中,每一个用户的事务都不受其它用户事务的干扰。
  • 完整性:事务提交前后,数据必须一致。
  • 持久性:事务一旦提交,对数据库的修改是永久的,即便电脑发生故障,也不会对数据造成影响。

spring的事务管理方式

事务管理常用接口

PlateformTransactionManager:事务管理器

TransactionDefinition:事务定义信息(传播行为、隔离级别、是否只读、超时信息等)

TransactionStatus:事务运行的状态

编程式事务管理(少用)

  • 第一步:配置文件中定义事务管理器
  • 第二步:配置文件中定义TransactionTemplate类信息,并将事务管理器注入到TransactionTemplate类中
  • 第三步:在需要使用事务的类中,添加TransactionTemplate类的属性并注入。
  • 第四步:在需要使用事务的方法中调用TransactionTemplate的execute方法,使用事务(需要用到TransactionCallbackWithoutResult类,可以使用匿名内部类)。
    代码如下:
/**
 * 转账业务类
 */
public interface UserService {

    /**
     * 转账操作
     * @param out   :转出金额账户
     * @param in    :转入金额账户
     * @param money :转账金额
     */
    public void transfer(String out, String in, Double money);

}

/**
 * 转账业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private TransactionTemplate transactionTemplate;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * 转账操作
     * @param out   :转出金额账户
     * @param in    :转入金额账户
     * @param money :转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                userDao.out(out, money);
                int i = 1/0;
                userDao.in(in, money);
            }
        });
    }

}

/**
 * 转账持久类
 */
public interface UserDao {

    /**
     * 转出金额
     * @param out:  转出金额账户
     * @param money:转出金额
     */
    public void out(String out, Double money);

    /**
     * 转入金额
     * @param in:   转入金额账户
     * @param money:转入金额
     */
    public void in(String in, Double money);

}

/**
 * 转账持久层实现类:使用Spring中的JdbcTemplate模板实现持久层
 */
public class UserDaoImpl implements UserDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 转出金额
     * @param out:  转出金额账户
     * @param money:转出金额
     */
    @Override
    public void out(String out, Double money) {
        String sql = "update account set money = money - ? where name = ?";
        jdbcTemplate.update(sql, money, out);
    }

    /**
     * 转入金额
     * @param in:   转入金额账户
     * @param money:转入金额
     */
    @Override
    public void in(String in, Double money) {
        String sql = "update account set money = money + ? where name = ?";
        jdbcTemplate.update(sql, money, in);
    }

}

applicationContext.xml内部如下:

    <!-- 引入jdbc Properties文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置 JdbcTemplate 模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="userService" class="com.spring.transaction.demo1.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

    <bean id="userDao" class="com.spring.transaction.demo1.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事务模板 --> 
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

声明式事务管理

接口和dao的实现类都是相同的代码,就不重复贴了。

基于TransactionProxyFactoryBean类的声明式事务管理(很少用)

具体代码如下:

/**
 * 转账业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 转账操作
     * @param out   :转出金额账户
     * @param in    :转入金额账户
     * @param money :转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
        userDao.out(out, money);
        int i = 1/0;
        userDao.in(in, money);
    }

}

applicationContext.xml如下:
<!-- 引入jdbc Properties文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置 JdbcTemplate 模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="userService" class="com.spring.transaction.demo2.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean id="userDao" class="com.spring.transaction.demo2.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置增强类 -->
    <bean id="transactionProxyFatoryBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="target" ref="userService"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

基于AspectJ的xml配置事务管理

具体代码如下:

/**
 * 转账业务实现类
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 转账操作
     * @param out   :转出金额账户
     * @param in    :转入金额账户
     * @param money :转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
        userDao.out(out, money);
//      int i = 1/0;
        userDao.in(in, money);
    }

}

applicationContext.xml如下:
<!-- 引入jdbc Properties文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置 JdbcTemplate 模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="userService" class="com.spring.transaction.demo3.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean id="userDao" class="com.spring.transaction.demo3.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置切面 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.spring.transaction.demo3.*.*(..))" id="transactionAspect"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionAspect"/>
    </aop:config>

基于注解的事务管理

具体代码如下:

/**
 * 转账业务实现类
 */
@Transactional(propagation=Propagation.REQUIRED)
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    /**
     * 转账操作
     * @param out   :转出金额账户
     * @param in    :转入金额账户
     * @param money :转账金额
     */
    @Override
    public void transfer(String out, String in, Double money) {
        userDao.out(out, money);
        int i = 1/0;
        userDao.in(in, money);
    }

}

applicationContext.xml如下:
<!-- 引入jdbc Properties文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 配置 JdbcTemplate 模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="userService" class="com.spring.transaction.demo4.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean id="userDao" class="com.spring.transaction.demo4.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 启用事务注解 -->
    <tx:annotation-driven/>
jdbc.properties如下:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://localhost\:3306/test
jdbc.username=root
jdbc.password=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值