spring的一些提醒

 

1、通过ApplicationContext的getBean方法返回的class只能用接口去转型(因为他是一个代理),当然如果你定义的类本身不继承任何接口的话,那么你就杯具了。

2、@Transactional这个事务标记,必须标记在service的入口方法处,否则不会生效的,一下几种情况,不会生效:

    a、入口方法没有标记@Transactional,但是入口方法调用本类的私有方法,该私有方法标记了@Transactional

   b、入口方法没有标记@Transactional,但是入口方法调用本类的共有方法,该共有方法标记了@Transactional,此处共有方法不论是否在接口中有定义都是一样的效果

   因为@Transactional默认采用的是AOP机制,当他基于spring自动生成的代理调用时,方才能够生效,所以上面几种情况不能够生效,也就可以理解了,所以要能够使@Transactional标记生效一般都是这样子调用的someService.someMethod()(someService最终会调用相应代理类的someMethod方法),someMethod上面标记@Transactional

   附:如果想使类中的私有方法以及方法内部之间的相互调用都能够让@Transactional生效的话,至少有两种方法可以解决:

   1) 将spring管理的自身类的实例注入到自己的类中,俗称自己注入自己,常见的是使用factory-method来管理本类的实例。

   2)使用aspectJ,这是spring的一项高级技术,我也不太懂,好像要对字节码进行修饰,但是确实是可以的,这也是spring推荐使用的解决方案,不过本人更倾向于第一种。

3、@Transactional标记会在方法执行完毕后才会commit。一般情况,程序执行到哪里的时候,抛出异常,回滚前面的操作就可以了,但是某些数据库异常却是在commit的时候抛出来的,这时我们就要注意了,不仅需要回滚抛出异常之前的代码,整个程序都需要进行回滚,注意如下代码:

@Transactional

public void oneMethod() {

           someJdbcOprate();//插入数据库操作

           insertSomeToMem();//插入某数据到内存中

}

注意这个方法,我们预想someJdbcOprate方法抛出异常后,就不会执行insertSomeToMem这个方法了,但实际可能并非如此,如果在事务commit时,抛出了某个数据库异常,则insertSomeToMem已经执行,且他执行的操作是没法回滚的,所以在使用@Transactional标记时,一定要清楚程序可能抛出的数据库异常,否则就可能出现问题。那么,有哪些情况是在事务commit的时候抛出数据库异常呢,请看如下情况:

  a、插入的值的长度大于数据库对应的列的长度。例如数据库中某一列长度是40个字符,可是你却插入了50个字符,此时在事务未提交之前是不会抛出异常的,只有在commit的时候才会抛出异常(java.sql.BatchUpdateException: ORA-01438: 值大于为此列指定的允许精度)

  b、插入了一个不存在的列的值。例如你想把“abc”插入表person中的name列,可是表person并没有name列,此时在事务内不会抛异常,也只有在方法结束commit的时候抛出异常。

  c、数据库中某列是一个不能为空的列,且在hbm中未设置改列的属性not-null="true",向该列插入了某个空值。此种情况也是在commit的时候抛出数据库异常。

 d、对于unique index,也会产生同样的问题。即数据库中某列标记为了unique index,并且存在某个值x,再次向该列插入值x,此时也不会在transactional内抛异常,也是在commit的时候抛的数据库异常。

  附:慎用spring的@Transactional标记。在@Transactional里面尽量只有数据库操作。

  注意:要解决以上问题,请具体参考我的另外一篇日志:spring+hibernate事务中无法即时使数据库检查约束的终极解决方案

4、在标记了@Transactional标记的方法中再次调用某个service的标记了@Transactional方法,则后面这个@Transactional会被忽略,这个commit和回滚以最外层的标记了@Transactional的方法为准。

5、@Transactional标记默认会在用户自定义的advice(就是自定义切面)之外执行,具体见图:

所以此时,想让自定义的aop能捕获@Transactional标记在commit时抛出的异常,需要在aop和<tx:annotation-driven />中设置属性order,通常order值越大,离业务方法越近,order值越小离方法越远(跟穿衣服一样,order值小的就只能位于最外面一层了),所以要捕获@Transactional方法抛出的异常,需要设置自己捕获异常的aop的order值比<tx:annotation-driven />中的order值小。

6、当使用spring+hibernate时,配置了session和当前线程(ThreadLocal)绑定,即在xml中配置了:

<filter>

        <filter-name>OpenSessionInViewFilter</filter-name>

        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>

        <init-param>

            <param-name>singleSession</param-name>

            <param-value>false</param-value><!--当为true的时候,整个请求使用同一个session(可能引发其他问题),当为false时,每一次dao请求即会产生一个session-->

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>OpenSessionInViewFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

如上配置,这样子,每个session的生命周期为,dao请求发起——>OpenSessionInViewFilter拦截器结束(即用户线程请求完毕),如果在一次请求的过程中,调用了多次dao,即生成多个session,我们知道一个session对应一个链接,这样子本次用户请求就可能占用多个数据库链接,当占用的链接数等于了datasource的maxactive的值的时候,其他用户再发起请求就会出现获取不到数据库链接的异常,因此,我们必须保证每个业务方法请求dao的次数尽量小于maxactive的值,实际上应该远远小于,而且尽可能将maxactive的值配置大一点。此种情况下maxactive的值也影响系统的并发数。

当然,也可以将singleSession的值配置为true,但是这样子可能引发一些潜在的问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 宿舍管理是一种基于Spring Boot框架开发的宿舍管理系统。该系统旨在提供一个便捷、高效、可靠的宿舍管理解决方案,帮助学校或宿舍管理人员更好地进行宿舍资源的管理与分配。 首先,Spring Boot 宿舍管理系统能够提供学生宿舍信息的录入与管理功能。管理员可以在系统中录入学生的基本信息,并为每位学生分配宿舍。系统还能够记录学生进出宿舍的时间,并实时统计宿舍人数,以方便宿舍管理人员掌握宿舍的使用情况。 其次,该系统还提供宿舍报修功能。学生可以通过系统在线提交宿舍报修申请,包括描述问题和上传照片等信息。宿舍管理人员收到报修请求后,能够及时处理并安排维修人员进行维修。 此外,该系统还具有宿舍设备管理功能。管理员可以在系统中记录宿舍内的设备信息,并进行设备的借用与归还管理。系统还能够提醒管理员设备的维护和更新,确保宿舍设备的正常运行。 最后,该系统还提供了个人账户功能。学生和宿舍管理人员都可以通过个人账户登录系统,查询个人信息、宿舍使用记录等。同时,系统还能够发送通知消息,提醒学生交纳宿舍费用、通知维修进度等重要信息。 综上所述,Spring Boot宿舍管理系统通过集成Spring Boot的快速开发特性,为宿舍管理提供了方便、高效的解决方案,提升了宿舍管理的效率和可靠性,让学校或宿舍管理人员更好地管理和维护宿舍资源。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值