spring中的事务控制

14 篇文章 1 订阅

一、建立数据库表

在这里插入图片描述
1.service代码

@Service
public class UserService {

    @Autowired
    private UserDao userDao;


    //service建一个转账的方法
    //模拟李四给张三转账
    public void zhuanzhang(){
        userDao.jian();
        int a = 10/0;
        userDao.add();
    }

}

2.Dao代码

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int add() {
        String sql = "update account set banlance = banlance + ? where username = '张三'";
        int update = jdbcTemplate.update(sql, 50);
        return update;
    }

    @Override
    public int jian() {
        String sql = "update account set banlance = banlance - ? where username = '李四'";
        int update = jdbcTemplate.update(sql, 50);
        return update;
    }
}

这里模拟的是李四给张三转账

3.xml代码

<?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:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd">


    <context:component-scan base-package="jdbc_tx.service"></context:component-scan>

    <!--引入命名空间-->
    <context:property-placeholder location="jdbc.properties"/>

    <!-- 创建数据库连接池Bean -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="${url}" />
        <property name="username" value="${uname}" />
        <property name="password" value="${password}" />
        <property name="driverClassName" value="${driverClassName}" />
    </bean>

    <!--创建JDBC模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
</beans>

4.测试代码

  @Test
    public void testTX(){

        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_tx.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.zhuanzhang();
    }

运行结果:再没有异常的情况下可以正常执行,
但当有异常时就会出现100,50的情况
在这里插入图片描述

二、解决(基于注解方式)

配置事务管理器
1.在xml中配置事务管理器,注入数据源,
在这里插入图片描述
2.开启事务注解驱动,指定事务管理器
在这里插入图片描述
3.在service层上的类加上@Transactional注解。
在这里插入图片描述

@Transactional注解的几个属性

@Transactional(
        readOnly = false,
        rollbackFor = Exception.class,
        isolation = Isolation.REPEATABLE_READ,
        propagation = Propagation.REQUIRED,
        timeout = 500000
)
/**
 *   readOnly = true,    是否只读:如果是只读,则只能进行读操作,不能写
     rollbackFor = Exception.class,   回滚异常
     noRollbackFor = NullPointerException.class,  不回滚的异常
     isolation = , 事务的隔离级别
     propagation =  事务的传播行为
     timeout = 超时时间  如果超出了某个时间不提交,则会回滚
    spring提供了7中传播行为
 */

三、解决(基于XML方式)

1.在xml中配置事务管理器

<!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

2.创建事务通知(增强)

 <!--配置通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--配置事务属性-->
        <tx:attributes>
            <!--指定哪种规则的方法上面添加事务-->
            <tx:method name="zhuanzhang*" isolation="DEFAULT" read-only="false" timeout="-1" propagation="REQUIRED" />
            <tx:method name="delete*" isolation="DEFAULT" read-only="false" timeout="-1" propagation="REQUIRED" />
            <tx:method name="update*" isolation="DEFAULT" read-only="false" timeout="-1" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

3.创建切入点和切面

 <!--配置切入点和切面-->
    <aop:config>
        <!--配置切入点表达式-->
        <aop:pointcut id="myPoint" expression="execution(* jdbc_tx.service.UserService.*(..))"></aop:pointcut>
        <!--配置切面-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint"></aop:advisor>
        
    </aop:config>

四、完全注解式开发

@Configuration //配置类
@ComponentScan(basePackages = "com.atguigu") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
 //创建数据库连接池
 @Bean
 public DruidDataSource getDruidDataSource() {
 DruidDataSource dataSource = new DruidDataSource();
 dataSource.setDriverClassName("com.mysql.jdbc.Driver");
 dataSource.setUrl("jdbc:mysql:///user_db");
 dataSource.setUsername("root");
 dataSource.setPassword("root");
 return dataSource;
 }
 //创建 JdbcTemplate 对象
 @Bean
 public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
 //到 ioc 容器中根据类型找到 dataSource
 JdbcTemplate jdbcTemplate = new JdbcTemplate();
 //注入 dataSource
 jdbcTemplate.setDataSource(dataSource);
 return jdbcTemplate;
 }
 //创建事务管理器
 @Bean
 public DataSourceTransactionManager
getDataSourceTransactionManager(DataSource dataSource) {
 DataSourceTransactionManager transactionManager = new
DataSourceTransactionManager();
 transactionManager.setDataSource(dataSource);
 return transactionManager;
 }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值