• 20-spring_事务


    目录:


     Spring对jdbc的支持

    1)原始jdbc操作数据库过程:

            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb", "username", "password");
            PreparedStatement prepareStatement = conn.prepareStatement("insert into users(name) values('test')");
            prepareStatement.executeUpdate();
            prepareStatement.close();

    2)Spring对jdbc的支持jar包:

    3)Spring对jdbc支持实现代码示例:

    • package claire.jdbc;
      
      public class User {
          private int id;
          private String name;
          private int age;
          
          
          public User() {
              super();
          }
          public User(String name, int age) {
              super();
              this.name = name;
              this.age = age;
          }
          public int getId() {
              return id;
          }
          public void setId(int id) {
              this.id = id;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          
          
      }
      User实体类
      package claire.jdbc;
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
      
      import javax.sql.DataSource;
      
      import org.springframework.jdbc.core.JdbcTemplate;
      
      public class UserDao {
      
          private JdbcTemplate jdbcTemplate;
      
          public void save(User user) throws Exception {
              //执行sql语句
              jdbcTemplate
                      .update("insert into users(name) values(?)", user.getName());
          }
      
          public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
              this.jdbcTemplate = jdbcTemplate;
          }
      
      }
      UserDao
      <?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:p="http://www.springframework.org/schema/p"
          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-4.3.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
      
          <context:component-scan base-package="claire"></context:component-scan>
          <!-- 示例化连接池 -->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
              <property name="url" value="jdbc:mysql://localhost:3306/javaweb"></property>
              <property name="username" value=""></property>
              <property name="password" value=""></property>
              <property name="initialSize" value="6"></property>
              <property name="maxActive" value="2"></property>
          </bean>
          
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          
          <bean id="userDao" class="claire.jdbc.UserDao">
              <property name="jdbcTemplate" ref="jdbcTemplate"></property>
          </bean>
      </beans>
      applicationContext.xml
      package claire.jdbc;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class Aop {
          @Test
          public void test() throws Exception{
              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
              UserDao user = (UserDao)ac.getBean("userDao");
              user.save(new User("dudu", 21));
          }
      }
      test

    4)Spring数据访问模板化:

      spring在数据访问过程中采用模板方法模式,对于不同的持久化机制,提供了不同的数据访问模板。不论我们采用什么样的技术,都需要一些特定的数据访问步骤。例如,我们都需要获取一个到数据存储的连接并在处理完成后释放资源,这是数据访问的固定步骤,但是每中数据访问的方法又会有些不同。我们会查询不同的对象以不同的方式进行更新,这是数据访问中变化的部分。

    • Spring提供给不同持久化机制的访问模板:
    模板类(org.springframework.*) 用途
    jca.cci.core.CciTemplate JCA CCI连接
    jdbc.core.JdbcTemplate JDBC连接
    jdbc.core.namedparam.NamedParameterJdbcTemplate 支持参数命名的JDBC连接
    orm.hibernate3.HibernateTemplate Hibernate 3.x以上的session
    orm.ibatis.SqlMapClientTemplate IBATIS SqlMap客户端
    orm.jdo.JdoTemplate Java数据对象实现
    orm.jpa.JpaTemplate Java持久化Api的实体管理器

    5)Spring在配置文件中加载property文件

    • jdbc.driverClassName=com.mysql.jdbc.Driver
      jdbc.url=jdbc:mysql://127.0.0.1:3306/javaweb
      jdbc.username=root
      jdbc.password=wyd
      jdbc.initialSize=6
      jdbc.maxActive=2
      <?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:p="http://www.springframework.org/schema/p"
          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-4.3.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
      
          <context:property-placeholder location="classpath:db.properties"/>
          <!-- 示例化连接池 -->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="${jdbc.driverClassName}"></property>
              <property name="url" value="${jdbc.url}"></property>
              <property name="username" value="${jdbc.username}"></property>
              <property name="password" value="${jdbc.password}"></property>
              <property name="initialSize" value="${jdbc.initialSize}"></property>
              <property name="maxActive" value="${jdbc.maxActive}"></property>
          </bean>
          
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          
          <bean id="userDao" class="claire.jdbc.UserDao">
              <property name="jdbcTemplate" ref="jdbcTemplate"></property>
          </bean>
      </beans>
      applicationContext.xml

      注意!!!!!:在配置这些配置信息时,可以使用与DataSource类中变量相同的名称,但是username属性不可以保持原样,如果在properties文件中也设置username=***,程序在运行的时候就会报错(org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'claire'@'localhost' (using password: YES)) )。上述例子在所有变量前加入了jdbc前缀,可以不加,但是要改变username的名称,比如可以直接存成“name"等。


     实现事务 

    1)简介:

      事务:通过事务,使以下方法要么全成功,要么全失败。spring使用aop技术实现声明式事务管理,可以并且只能为某个方法添加事务控制,是一种粗粒度的事务控制。


      *事务控制在service层。

    2)XML方式配置:

    • 引入jar包包括:spring核心包,Spring aop编程包, Spring-jdbc, Spring-tx , 驱动包, 连接池。
    • 具体配置:
      • 配置数据源
        <bean id="dataSource"
                class="org.apache.commons.dbcp.BasicDataSource">
                <property name="driverClassName"
                    value="com.mysql.jdbc.Driver"></property>
                <property name="url"
                    value="jdbc:mysql://localhost:3306/javaweb"></property>
                <property name="username" value=""></property>
                <property name="password" value=""></property>
                <property name="maxActive" value="10"></property>
                <property name="maxIdle" value="6"></property>
            </bean>
      1. 配置JdbcTemplate,注入数据源
            <bean id="txManager"
                class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"></property>
            </bean>
      2. 事务通知配置,拦截到指定的方法后如何管理事务
        <tx:advice id="txAdvice" transaction-manager="txManager">
                <tx:attributes>
                    <tx:method name="find*" read-only="true"/>
                    <tx:method name="get*" read-only="true"/>
                    <tx:method name="*" read-only="false"/>
                </tx:attributes>
            </tx:advice>
      3. 事务aop配置= 切入点表达式 + 应用上面的事务通知
        <aop:config>
                <aop:pointcut expression="execution(* claire..*Service.*(..))" id="pt"/>
                <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
            </aop:config>
    • 完整代码:
      <?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:p="http://www.springframework.org/schema/p"
          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-4.3.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                              http://www.springframework.org/schema/tx 
                              http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
      
          <context:property-placeholder location="classpath:db.properties" />
          <!-- 配置数据源 -->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="${jdbc.driverClassName}"></property>
              <property name="url" value="${jdbc.url}"></property>
              <property name="username" value="${jdbc.username}"></property>
              <property name="password" value="${jdbc.password}"></property>
              <property name="initialSize" value="${jdbc.initialSize}"></property>
              <property name="maxActive" value="${jdbc.maxActive}"></property>
          </bean>
      
          <!-- 配置JdbcTemplate,注入数据源 -->
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
          <!-- dao实例,注入jdbcTemplate -->
          <bean id="userDao" class="claire.jdbc.UserDao">
              <property name="jdbcTemplate" ref="jdbcTemplate"></property>
          </bean>
      
          <!-- Service实例,注入dao实例 -->
          <bean id="userService" class="claire.jdbc.UserService">
              <property name="userDao" ref="userDao"></property>
          </bean>
      
          <!-- Spring声明式事务 -->
          <!-- 1. 配置事务管理器类 -->
          <bean id="txManager"
              class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          <!-- 2. 事务通知配置,拦截到指定的方法后如何管理事务 -->
          <tx:advice id="txAdvice" transaction-manager="txManager">
              <tx:attributes>
                  <tx:method name="find*" read-only="true"/>
                  <tx:method name="get*" read-only="true"/>
                  <tx:method name="*" read-only="false"/>
              </tx:attributes>
          </tx:advice>
          <!-- 3. 事务aop配置= 切入点表达式 + 应用上面的事务通知 -->
          <aop:config>
              <aop:pointcut expression="execution(* claire..*Service.*(..))" id="pt"/>
              <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
          </aop:config>
      </beans>
      applicationContext.xml
      package claire.jdbc;
      
      public interface IUserDao {
      
          void save();
      
      }
      IUserDao
      package claire.jdbc;
      
      import org.springframework.jdbc.core.JdbcTemplate;
      
      public class UserDao implements IUserDao {
      
          private JdbcTemplate jdbcTemplate;
      
          @Override
          public void save() {
              // 执行sql语句
              jdbcTemplate.update("insert into users(name) values('123')");
          }
      
          public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
              this.jdbcTemplate = jdbcTemplate;
          }
      
      }
      UserDao
      package claire.jdbc;
      
      public interface IUserService {
      
          void save();
      
      }
      IUserService
      package claire.jdbc;
      
      public class UserService implements IUserService{
          private UserDao userDao;
      
          @Override
          public void save(){
              userDao.save();
          }
          
          public void setUserDao(UserDao userdao) {
              this.userDao = userdao;
          }
      }
      UserService
      package claire.jdbc;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class App {
          @Test
          public void test() throws Exception{
              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
              IUserService userService = (IUserService)ac.getBean("userService");
              userService.save();
          }
      }
      test

     3)注解配置:

    • 具体配置:前几步同xml方式一样,略过2、3步,之后按如下设置:
      • 添加事务管理器
        <bean id="txManager"
                class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"></property>
            </bean>
      • spring增加对事务支持
        <tx:annotation-driven transaction-manager="txManager" />
      • 之后在相应Service类中想要添加事务控制的方法前加入@Transactional注解即可:

             @Transactional(

                      readOnly=false,      // 读写的事务,当修改数据时候用;如果查询就设置为true

                      isolation=Isolation.DEFAULT// 事务隔离级别

                      timeout=-1,            // 事务执行的超时时间, -1 表示不超时

                      noRollbackFor=ArithmeticException.class,   // 遇到指定的异常不回滚

                      propagation=Propagation.REQUIRES_NEW      // 事务传播行为(值可以为REQUIRES_NEWREQUIRED、SUPPORTS、Never等

             )

            @Transactional
            @Override
            public void save(){
                userDao.save();
            }
    • 完整代码:
      package claire.jdbc;
      
      public interface IUserDao {
      
          void save();
      
      }
      IUserDao
      package claire.jdbc;
      
      public interface IUserService {
      
          void save();
      
      }
      IUserService
      package claire.jdbc;
      
      import javax.annotation.Resource;
      
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.stereotype.Repository;
      
      @Repository
      public class UserDao implements IUserDao {
      
          @Resource
          private JdbcTemplate jdbcTemplate;
      
          @Override
          public void save() {
              // 执行sql语句
              jdbcTemplate.update("insert into users(name) values('123')");
          }
      }
      UserDao
      package claire.jdbc;
      
      import javax.annotation.Resource;
      
      import org.springframework.stereotype.Service;
      import org.springframework.transaction.annotation.Transactional;
      
      @Service
      public class UserService implements IUserService{
          @Resource
          private UserDao userDao;
      
          @Transactional
          @Override
          public void save(){
              userDao.save();
          }
          
          public void setUserDao(UserDao userdao) {
              this.userDao = userdao;
          }
      }
      UserService
      <?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:p="http://www.springframework.org/schema/p"
          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-4.3.xsd
                              http://www.springframework.org/schema/aop
                              http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                              http://www.springframework.org/schema/tx 
                              http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
      
          <context:property-placeholder location="classpath:db.properties" />
          <!-- 配置数据源 -->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="${jdbc.driverClassName}"></property>
              <property name="url" value="${jdbc.url}"></property>
              <property name="username" value="${jdbc.username}"></property>
              <property name="password" value="${jdbc.password}"></property>
              <property name="initialSize" value="${jdbc.initialSize}"></property>
              <property name="maxActive" value="${jdbc.maxActive}"></property>
          </bean>
      
          <!-- 配置JdbcTemplate,注入数据源 -->
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
          <!-- 开启注解扫描 -->
          <context:component-scan base-package="claire"></context:component-scan>
          <!-- 增加对事务支持 -->
          <tx:annotation-driven transaction-manager="txManager"/>
      
      </beans>
      bean.xml
      package claire.jdbc;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class App {
          @Test
          public void test() throws Exception{
              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
              IUserService userService = (IUserService)ac.getBean("userService");
              userService.save();
          }
      }
      test
  • 相关阅读:
    Win10安装.NetFamework3.5
    SAN和NAS的区别
    raid10模型比raid01模型的冗余度高
    Linux——查找占用磁盘体积最大的前10个文件
    Nginx——端口负载均衡
    oneinstack——证书更新
    SpringBoot——IDEA使用 Spring Initializer快速创建项目【四】
    Nginx——请求head被过滤
    Linux—— 记录所有登陆用户的历史操作记录
    Nginx——跨域造成的504问题
  • 原文地址:https://www.cnblogs.com/clairexxx/p/10422332.html
Copyright © 2020-2023  润新知