首页 > 编程知识 正文

spring中常用的注解以及作用,spring自定义注解

时间:2023-05-03 16:45:06 阅读:106036 作者:3711

适用于@Transactional用法接口、接口方法、类和类方法。

当用于类时,该类的所有公共方法都具有该类型的事务属性,并且可以在方法级别使用此标注来复盖类级别的定义。 方法的其馀属性是类的事务属性。 Spring建议不要在接口或接口方法中使用此注释。 只有在使用基于接口的代理时,这才有效。 另外,@Transactional注释应该只适用于public方法,这是由Spring AOP的本质决定的。 如果以protected、private或默认可见性方式使用@Transactional注释,则此选项将被忽略,并且不会抛出异常。 缺省情况下,AOP代理仅捕获外部方法调用。 这意味着,如果调用由@Transactional注释限定的方法,则当类内部的方法调用类内部的其他方法时,不会发生事务行为。 缺省情况下,仅当抛出的异常是运行时unchecked异常时,Spring才会回退事务。 这意味着抛出的异常是RuntimeException的子类,Errors将回退事务。 抛出checked异常不会回滚事务。 (可以明确设置哪些异常时回滚,哪些异常时不回滚)知识点扩展: Java异常详细信息

@Transactional属性属性类型说明valueString选项的限定描述符、 要使用的事务管理器传播事件:传播选项的事务传播行为设置isolationenum:Isolation选项的事务隔离级别设置readOnlyboolean默认值写入timeoutint(seconds )事务超时设置rollbackForClass对象数组,Throwable将回退事务的异常类数组rollbackForClass 必须从通过Throwable回滚事务的异常类名数组noRollbackForClassName对象数组继承,并且事务不会通过Throwable回滚的异常类数组norollble

@ transactional (propagation=propagation.required,isolation=Isolation.DEFAULT,readOnly=true,timeout=200, readonly=true rollbackforclassname={ ' sqlexception ' },norollbackfor={ sqlexception.class } (publicpageinfouserpager )

Propagation.REQUIRED :如果当前存在事务,则参与该事务; 如果当前没有事务,请创建新事务。 这是默认值。 (缺省) Propagation.SUPPORTS )如果当前存在事务,则参与该事务; 如果当前没有事务,请以事务以外的方式继续。 Propagation.MANDATORY :如果当前存在事务,则参与该事务; 如果当前没有事务,则抛出异常Propagation.REQUIRES_NEW。 创建新事务。 如果当前有事务,则当前挂起事务。 Propagation.NOT_SUPPORTED :作为非事务执行,当前挂起事务(如果当前有事务)。 Propagation.NEVER :作为非事务执行,如果当前存在事务,则抛出异常Propagation.NESTED。 如果当前有事务,请创建当前作为事务嵌套事务执行的事务。 如果当前没有事务,则此值与transaction definition.propagation _ required相同。 注意: REQUIRES_NEW和NESTED都正在打开新事务。 不是吗?

REQUIRES_NEW是打开一个完整的新事务,与当前事务没有任何关系。

单独失败、回滚、提交。 不依赖外部事务。 在执行新事务过程中,旧事务被搁置。

NESTED也会启动新事务,但会启动基于当前事务的子事务。 如果失败,则单独回滚;如果成功,则等待外部事务的执行结果,而不是立即提交。 如果外部事务提交,则提交子事务。

Propagation枚举: 事务传播行为(底层是TransactionDefinition.PROPAGATION_XX)

Isolation.DEFAULT :默认值。 这意味着使用基础数据库的缺省隔离级别。 Isolation.READ_UNCOMMITTED :隔离级别表示一个事务读取已被另一个事务修改但未提交的数据。 在这个水平上不能防止脏读。 不能反复读取或幻读。

因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。Isolation.READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。Isolation.REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。Isolation.SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

事务隔离级别详解:https://blog.csdn.net/qq_36792191/article/details/104022886?spm=1001.2014.3001.5502

知识点扩展:源码级别解读

@Transactional不生效的解决方案

1.常见不生效原因

项目未配置支持事物!概率较小方法内部使用try-catch捕获了异常。概率较大方法非public。概率较小事物未显示指定回滚异常,概率较小,因为一般抛出的异常都是运行时异常同一类中方法互相调用。概率极大

2.同一类中方法互相调用的解决方案

情形:(1)同一个类无@Transational的A方法调用有@Transational的B方法,B方法的事物无效。(2)同一类中有@Transational的A方法调用有@Transational的B方法,B方法的事物传播级别是新建事物REQUEST_NEW,B方法的事物无效。

解决:1.新建一个类装盛B方法

2.采用代理的设计模式构建通用的事物接口

//步骤一:声明事务接口public interface TransactionalSupportService { /** * 声明新的事务、然后执行业务代码 */ void newTransactional(Consumer consumer);}//步骤二:声明事务客户端public interface Consumer { /** * 对具体业务代码的传递 */ void accept();}//步骤三:提供事务的代理@Servicepublic class TransactionalSupportServiceImpl implements TransactionalSupportService { @Override @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) public void newTransactional(Consumer consumer){ consumer.accept(); }}//步骤四:应用...transactionalSupportService.newTransactional(new Consumer() { @Override public void accept() { groupIds.clear(); //...业务代码 } });

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。