网站首页
Java
站长
开源
框架
理论
JS
Linux
DB
服务器
网络编程
生活
软件
PHP
其他
回复Java小强

黑马程序员,Java面试题视频教程中提取的,关于Spring事物不起作用的原因: (1)没有处理检查异常,比如FileNotFindException,Spring默认只回滚非检查异常 在@Transactional注解添加rollbackFor=Exception。 (2)自己处理try-catch导致Spring无法获知异常 异常向上抛出,或者手动设置TransactionInterceptor.currentTransactionStatus.setRollbackOnly()。 (3)自定义AOP切面顺序 默认自己写一个切面的优先级和事物是一样的,都是最低,但是Spring默认先执行事物的再执行自定义的,如果自定义切面中出现(2)情况事物失效。 切面中处理参考(2),或者调整切面顺序,让自定义切面优先级高于Spring事物切面。 (4)非public方法 默认Spring为方法创建代理,添加事物通知,前提都是该方法都是public的。 (5)父子容器导致,子容器扫描范围过大 各自扫描各自的包,或者不要使用父子容器。 如果使用了SpringMVC,SpringMVC只扫描Controller包。 (6)Spring事物传播行为配置不当 如果同一个service中A使用this调用方法B,这时B上的事物注解无效。 方法B提取到不同的service中,也可以在本service中注入自己然后通过该对象进行调用。或者通过spring获取当前代理对象来调用((ABService)AopContext.currentProxy()).B()但是要配置exposeProxy=true。也可以通过CTW或LTW实现功能增强。 (7)多线程情况下@Transactional没有保证原子性 事物原子性覆盖insert,update,delete,select...for update语句,select方法不堵塞,因此在一个更新没有提交时,再次查询到的是之前数据。因此要在查询时使用for update来堵塞其他线程对该数据的任何操作。 (8)@Transactional方法导致的synchronized失效 synchronized保证了目标方法原子性,但是spring事物的环绕commit等操作并不能保证,因为他们不在sync块内。因此sync要加载代理方法调用之前,比如在Controller内调用时就加。或者使用(7)方法来解决。

您的网名:
个人主页:
编辑内容: