事务(Transaction)/@RequestMapping注解

目录

1.事务(Transaction)

2. 关于@RequestMapping注解


1.事务(Transaction)

事务是数据库中的可以保证多个(至少2个)写操作(增、删、改)要么全部执行成功,要么全部执行失败的机制!

在基于Spring JDBC的项目中,使用@Transactional注解,即可使得注解的方法是事务性的。

关于@Transactional注解,可以添加在:

  • 接口上
    • 等效于在每个抽象方法上添加了此注解
  • 接口的抽象方法上
    • 仅作用于当前方法(重写的方法运行时)
  • 实现类上
    • 等效于在每个重写的接口的方法上添加了此注解
  • 实现类中重写的接口的方法上
    • 仅作用于当前方法

提示:此注解可以配置一些参数,如果同时在接口/类、接口的抽象方法/类重写的方法上添加此注解并配置了不同的参数值,则以方法上的配置为准。

注意:Spring JDBC是基于接口的代理模式来实现事务管理的!所以,如果在实现类中的自定义方法上添加@Transactional注解是错误的做法!仅当对应的方法是在业务接口中已经声明的,使用@Transactional才是正确的!

关于事务处理过程中的几个概念:

  • 开启事务:BEGIN
  • 提交事务:COMMIT
  • 回滚事务:ROLLBACK

在Spring JDBC的事务管理中,大致是:

开启事务
try {
	执行你的业务方法
	提交事务
} catch (RuntimeException e) {
	回滚事务
}

可以看到,Spring JDBC的事务管理中,默认将根据RuntimeException进行回滚,可以通过@Transactional注解的rollbackFor / rollbackForClassName这2个属性中的某1个进行修改,设置为对特定的异常进行回滚,还可以配置noRollbackFor / noRollbackForClassName这2个属性,设置对特定的异常不回滚。

【小结】关于事务:

  • 如果某个业务方法涉及超过1次的增、删、改操作,需要保证此业务方法是事务性的;
  • 推荐在业务的抽象方法上添加@Transactional注解即可保证此业务方法是事务性
    • 对于初学者,更推荐在业务接口上添加@Transactional,则此接口中所有抽象方法都是事务性,可能其中的某些抽象方法并不需要是事务性的,但是,这种做法比较稳妥,能避免遗漏导致的错误
  • 为了保证事务能够按照预期进行回滚,需要:
    • 业务层必须由接口和实现类组成
      • Spring JDBC是基于接口代理模式实现事务管理的,如果没有接口,则无法实现
    • 所有增、删、改操作完成后,应该及时获取返回结果,并对结果进行判断,如果结果不符合预期,应该抛出异常,且异常应该是RuntimeException或其子孙类异常
      • Spring JDBC在管理事务时,默认按照RuntimeException进行回滚

2. 关于@RequestMapping注解

在Spring MVC框架中,@RequestMapping注解的主要作用是:绑定“请求路径”与“处理请求的方法”的映射关系。

关于此注解的声明的源代码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
}

以上源代码中的@Target({ElementType.TYPE, ElementType.METHOD})就表示了此注解可以添加在哪里,其中,ElementType.TYPE表示可以添加在“类型”上,ElementType.METHOD表示可以添加在方法上。

在控制器类上,添加@RequestMapping配置的路径值,将作为当前控制器类中每个处理请求的路径的前缀部分!例如在类上配置为@RequestMapping("/brands"),在方法上配置为@RequestMapping("/delete"),则完整路径为/brands/delete,并且,此控制器类中所有处理请求的方法的路径上都有/brands前缀!

所以,强烈推荐在每个控制器类上都使用@RequestMapping配置路径的前缀部分。

关于注解内部的源代码,以@RequestMapping为例,其内部有:

String name() default "";

以上源代码中,name()表示此注解有名为name的属性,左侧的String表示此属性的数据类型,右侧的default ""表示此属性的默认值。例如:可以在@RequestMapping中配置名为name的属性:

@RequestMapping(name = "test")

@RequestMapping中,还有:

@AliasFor("path")
String[] value() default {};

则以上源代码表示:此注解中有名为value的属性,值是String[]类型的,则默认值是空数组。

在Java语言中,注解的value属性是默认的属性,如果注解只需要配置这1个属性的值,则可以不必显式的声明属性名称,例如:

@RequestMapping(value = {"value1", "value2", "value3"})
@RequestMapping({"value1", "value2", "value3"})

以上2种配置是完全等效的!

在Java语言中,如果某个属性的值是某种数组类型,但是,配置的数组值只有1个元素,则不必使用大括号将其框住,例如:

@RequestMapping(value = {"value1"})
@RequestMapping(value = "value1")

以上2种配置是完全等效的!

关于源代码中value属性的声明,还添加了@AliasFor("path"),表示此value属性等效于当前注解中的path属性!

@RequestMapping注解的源代码中,还有:

RequestMethod[] method() default {};

以上注解的作用是“限制请求方式”,在没有配置此属性的情况,任何请求方式都是允许的!例如:

@RequestMapping(value = "/add-new", method = RequestMethod.POST)

如果使用以上配置,则/add-new路径只允许通过POST方式提交请求,如果使用其它请求方式,将出现405错误!

强制推荐将所有请求都限制请求方式!

在Spring MVC框架中,还定义了相关注解,以简化限制请求方式的配置:

  • @GetMapping
  • @PostMapping
  • PutMapping
  • DeleteMapping
  • PatchMapping

以上这些都相当于是限制了请求方式的@RequestMapping

小结:

  • 推荐在每个控制器类上使用@RequestMapping配置请求路径前缀
  • 推荐在每个处理请求的方法上使用@GetMapping / @PostMapping配置请求路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值