统计
  • 建站日期:2021-03-10
  • 文章总数:518 篇
  • 评论总数:151 条
  • 分类总数:32 个
  • 最后更新:4月20日
文章 Spring

spring第四天自己总结的笔记和代码疑点难点重点

梦幻书涯
首页 Spring 正文

<context:component-scan base-package="com.sise"></context:component-scan>



    <!--记住用spring提供的内置事务管理器,就不需要线程和当前链接绑定(也就是说ConnectionUtils这个类可以删除)

    而且Impl.daoimpl类中的sqlq语句不能加Connectionutils.getThreadConnection(),否则事务失败,spring本身已经弄好了

    -->

    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">

        <constructor-arg name="ds" ref="datasource"></constructor-arg>

    </bean>



    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>

        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/item"></property>

        <property name="user" value="root"></property>

        <property name="password" value="8438031100"></property>

    </bean>

    <!-- spring中基于注解的声明式事务控制配置步骤

    也就是spring本身提高事务管理机制不需要写TransactionManager这个类



    步骤如下:



    1:配置事务管理器

    -->

    <!--第一步:

             配置事务管理器,也就是这个jar(类)是spring自带的,它自动实现事务功能-->

    <bean id="transactionmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="datasource"></property>

    </bean>

    <!--第二步:开启spring对注解形式的事务管理功能-->

      <tx:annotation-driven transaction-manager="transactionmanager"></tx:annotation-driven>



    <!-- spring中基于注解 的声明式事务控制配置步骤

       1、配置事务管理器

       2、开启spring对注解事务的支持

       3、在需要事务支持的地方使用@Transactional注解-->

</beans>






<!--记住用spring提供的内置事务管理器,就不需要线程和当前链接绑定(也就是说ConnectionUtils这个类可以删除)
    而且Impl.daoimpl类中的sqlq语句不能加Connectionutils.getThreadConnection(),否则事务失败,spring本身已经弄好了
    -->
    <!--配置Acountservice-->

    <bean id="acountService" class="com.sise.service.impl.AcountServiceImpl">
        <property name="iAcountDao" ref="acountDao"></property>
    </bean>

    <!--配置AcountDao-->
    <bean id="acountDao" class="com.sise.dao.impl.AcountDaoImpl">
        <property name="runner" ref="runner"></property>
    </bean>
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--注入数据源-->
        <!-- 这个1语句:<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
        <!-- 如果想线程和连接绑定,则需要再daoImpl里面的sql语句前面添加connectionUtils.getThreadConnection(),

        return runner.query(connectionUtils.getThreadConnection(),"select * from mybatisacount"
        , new BeanListHandler<AcountBean>(AcountBean.class));

        而且要注掉这个1语句:<constructor-arg name="ds" ref="dataSource"></constructor-arg>
        这个语句不注掉,就会创建多个连接,使事务不能使用


        -->
        <!--        <property name="runner" ref="runner"></property>  用这个就会出现错误-->

    </bean>

    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/item"></property>
        <property name="user" value="root"></property>
        <property name="password" value="8438031100"></property>
    </bean>
    <!-- spring中基于XML的声明式事务控制配置步骤
    也就是spring本身提高事务管理机制不需要写TransactionManager这个类

    步骤如下:

    1:配置事务管理器
    -->
    <!--第一步:
             配置事务管理器,也就是这个jar(类)是spring自带的,它自动实现事务功能-->
    <bean id="transactionmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <!--第二步:
            配置事务通知功能
    使用的标签是<tx:advice> </tx:advice>,并且再中间配置事务属性标签-><tx:attributes></tx:attributes>
    属性: id:给事务通知起一个唯一标识
          transaction-manager:给事务通知提供一个事务管理器引用,也就是第一步配置的事务管理器的id(唯一标识)-->
    <tx:advice id="txAdvice" transaction-manager="transactionmanager">
        <!--配置事务的属性
                isolation: 用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
                propagation:用于指定事务的传播行为。默认值是REQUIRED,required,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
                no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
                read-only:read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
                rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
                timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。

        -->
        <tx:attributes>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!--
        3、配置AOP中的通用切入点表达式
        4、建立事务通知和切入点表达式的对应关系
        5、配置事务的属性
        是在事务的通知tx:advice标签的内部-->
    <aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.sise.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
    </aop:config>
</beans>




 <!--配置代理的service
    这个作用的意思:原来的acountService不能让事务成功进行,通过动态代理对象,
    将原来acountService的对象进行增强,从而让他有了事务功能,最终变成proxyAccountService,不过他也是IAcountService中一个对象
    -->
    <bean id="proxyAccountService" factory-bean="beanFactory" factory-method="getAccountService"></bean>

    <!--配置beanFactory工厂
    利用动态代理模式,使得 rtValue = method.invoke(iAcountService, args);
    iAcountService代理对象(IAcountService中所有接口办法都经过该代理对象)
    从而使得事务得以进行,
    我下面就配置aop(它也是利用动态代理功能实现的),有了aop就不需要beanFactory这个类了
    -->
    <bean id="beanFactory" class="com.sise.config.BeanFactory">
        <property name="txManager" ref="tx"></property>
        <property name="iAcountService" ref="acountService"></property>
    </bean>
    <!--配置Acountservice-->
    <bean id="acountService" class="com.sise.service.impl.AcountServiceImpl">
        <property name="iAcountDao" ref="acountDao"></property>
    </bean>

    <!--配置AcountDao-->
    <bean id="acountDao" class="com.sise.dao.impl.AcountDaoImpl">
        <property name="connectionUtil" ref="connectionutils"></property>
        <property name="runner" ref="runner"></property>
    </bean>


    <!--配置通知-->
    <bean id="tx" class="com.sise.utils.TransactionManager">
        <property name="connectionUtil" ref="connectionutils"></property>
    </bean>

    <!--配置当前线程和链接绑定-->

    <bean id="connectionutils" class="com.sise.utils.ConnectionUtil">
        <property name="dataSource" ref="datasource"></property>
    </bean>

    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--注入数据源-->
        <!-- 这个1语句:<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
        <!-- 如果想线程和连接绑定,则需要再daoImpl里面的sql语句前面添加connectionUtils.getThreadConnection(),

        return runner.query(connectionUtils.getThreadConnection(),"select * from mybatisacount"
        , new BeanListHandler<AcountBean>(AcountBean.class));

        而且要注掉这个1语句:<constructor-arg name="ds" ref="dataSource"></constructor-arg>
        这个语句不注掉,就会创建多个连接,使事务不能使用


        -->
        <!--        <property name="runner" ref="runner"></property>  用这个就会出现错误-->

    </bean>

    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/item"></property>
        <property name="user" value="root"></property>
        <property name="password" value="8438031100"></property>
    </bean>

    <aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.sise.service.impl.*.*(..))"/>
        <!--
        aop:aspect:id:唯一识别
        ref:切面类的唯一识别
        -->
        <aop:aspect id="logAdvice" ref="tx">
            <!--
            当注解aop时候只能环绕通知,其他通知出问题,
            xml配置的不管是其他通知还是环绕通知都可以
            -->
<!--            <aop:before method="beginTransaction" pointcut-ref="pt1"></aop:before>-->
<!--            <aop:after-returning method="commitTransaction" pointcut-ref="pt1"></aop:after-returning>-->
<!--            <aop:after-throwing method="rollbackTransaction" pointcut-ref="pt1"></aop:after-throwing>-->
<!--            <aop:after method="releaseTransaction" pointcut-ref="pt1"></aop:after>-->
            <aop:around method="aroundTransaction" pointcut-ref="pt1"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>





 private IAcountService iAcountService;

    private TransactionManager txManager;

    public void setiAcountService(IAcountService iAcountService) {
        this.iAcountService = iAcountService;
    }

    public void setTxManager(TransactionManager txManager) {
        this.txManager = txManager;
    }

    public IAcountService getAccountService() {
        return (IAcountService) Proxy.newProxyInstance(iAcountService.getClass().getClassLoader(), iAcountService.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object rtValue;
                try {
                    txManager.beginTransaction();
                    rtValue = method.invoke(iAcountService, args);
                    txManager.commitTransaction();
                    return rtValue;
                } catch (Exception e) {
                    txManager.rollbackTransaction();
                    throw new RuntimeException(e);
                } finally {
                    txManager.releaseTransaction();
                }

            }

        });

    }



public class transactionConfig {
    @Bean(name="txManager")
    public PlatformTransactionManager createTransaction(DataSource dataSource) {
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        return txManager;
    }

}


public class jdbcConfigg {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;


    @Bean(name="jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     */
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
}





@org.springframework.context.annotation.Configuration
@PropertySource("jdbc.properties")
@Import({jdbcConfig.class,transactionConfig.class})
@ComponentScan("com.sise")
@EnableTransactionManagement
public class Configuration {
}




@Service("acountService")
@Transactional(propagation= Propagation.SUPPORTS,readOnly=true)//只读型事务的配置
public class AcountServiceImpl implements IAcountService {

    @Autowired
    @Qualifier("acountdaoimpl")
    private IAcountDao iAcountDao;

//    public List<AcountBean> findAllAcount() {
//        List<AcountBean> allAcount = iAcountDao.findAllAcount();
//        return allAcount;
//    }

    public AcountBean findAcountById(int acountId) {
        return iAcountDao.findAccountById(acountId);
    }

    //需要的是读写型事务配置
    @Transactional(propagation= Propagation.REQUIRED,readOnly=false)
    public void transfer(String sourceName, String targetName, int money) {
        AcountBean Sourcename = iAcountDao.findAccountByName(sourceName);
        AcountBean Targetname = iAcountDao.findAccountByName(targetName);
        Sourcename.setMoney(Sourcename.getMoney() - money);
        Targetname.setMoney(Targetname.getMoney() + money);
        iAcountDao.updateAccount(Sourcename);
        int i = 3 / 0;
        iAcountDao.updateAccount(Targetname);
    }

版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。
版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!

这篇文章最后更新于2020-3-4,已超过 1 年没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
spring框架常用的pop.xml下的jar坐标(maven)工程
« 上一篇
spring第四天老师讲的笔记的代码总结
下一篇 »

发表评论

HI ! 请登录
注册会员,享受下载全站资源特权。
Array

日历

热门文章