关于开发中的Spring(一)

问题描述:

今天在写代码的时候,在进行一个保存操作的时候,代码可以成功执行,没有报错,但是数据库里对应的表里没有这条数据,而且,控制台也没有打印出插入的SQL语句。这就很疑惑。

为什么不去执行相应的插入逻辑呢,后来问了一下同事,说出原因的那一刻,都感觉自己很蠢。

问题原因:

在Spring的配置文件中配置了相应的切点,那么我会在在相应的切点执行对应的事务操作。那么这个事务操作平时我们都怎么配置的呢,基本都是在XML文件里指定的,如:

这里指定了触发事务对应的方法名字,通过<tx:method>进行配置,例如:在我配置切点的位置,所有以insert开头的方法名称,都会触发事务操作。下面还有很多,这里的还配置了在什么情况下回滚事务,也就是 rollback-for="Exception",执行异常时事务回滚。这里的propagation是指对事务的控制,就是什么时候新增一个事务,什么时候用当前的事务等等,不了解的可以自行百度。最要命的是最后一项,

Spring事务传播属性用的比较多的也就是下面这几项:

也就是REQUIRED和SUPPORTS.

REQUIRED--如果当前要执行事务时发现没有,则新建一个事务

SUPPORTS--如果当前执行的代码在事务中,就以事务的方式进行,如果不在事务中,就以非事务的方式进行

我的代码犯的错误

方法命名并不是XML里<tx:method>里面定义的那些,我的方法名是cancel,可以看出并没有触发到对应的事务。

同时,XML配置文件中,对于其他方法名称的配置,是SUPPORTS,可以看到,这就是为什么触发不了事务的原因了。

下面介绍下Spring配置文件中事务的几个传播属性,如下:(感谢这位博主的分享)

1: REQUIRED

加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务

比如说,DemoServiceB.demoMethodB的事务级别定义为REQUIRED, 那么由于执行DemoServiceA.demoMethodA的时候,

DemoServiceA.demoMethodA已经起了事务,这时调用DemoServiceB.demoMethodB,DemoServiceB.demoMethodB看到自己已经运行在DemoServiceA.demoMethodA

的事务内部,就不再起新的事务。而假如DemoServiceA.demoMethodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。

这样,在DemoServiceA.demoMethodA或者在DemoServiceB.demoMethodB内的任何地方出现异常,事务都会被回滚。即使DemoServiceB.demoMethodB的事务已经被

提交,但是DemoServiceA.demoMethodA在接下来fail要回滚,DemoServiceB.demoMethodB也要回滚

2: SUPPORTS

如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行

3: MANDATORY

必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常

4: REQUIRES_NEW

这个就比较绕口了。 比如我们设计DemoServiceA.demoMethodA的事务级别为REQUIRED,DemoServiceB.demoMethodB的事务级别为REQUIRES_NEW,

那么当执行到DemoServiceB.demoMethodB的时候,DemoServiceA.demoMethodA所在的事务就会挂起,DemoServiceB.demoMethodB会起一个新的事务,等待DemoServiceB.demoMethodB的事务完成以后,

他才继续执行。他与REQUIRED 的事务区别在于事务的回滚程度了。因为DemoServiceB.demoMethodB是新起一个事务,那么就是存在

两个不同的事务。如果DemoServiceB.demoMethodB已经提交,那么DemoServiceA.demoMethodA失败回滚,DemoServiceB.demoMethodB是不会回滚的。如果DemoServiceB.demoMethodB失败回滚,

如果他抛出的异常被DemoServiceA.demoMethodA捕获,DemoServiceA.demoMethodA事务仍然可能提交。

5: NOT_SUPPORTED

当前不支持事务。比如DemoServiceA.demoMethodA的事务级别是REQUIRED ,而DemoServiceB.demoMethodB的事务级别是NOT_SUPPORTED ,

那么当执行到DemoServiceB.demoMethodB时,DemoServiceA.demoMethodA的事务挂起,而他以非事务的状态运行完,再继续DemoServiceA.demoMethodA的事务。

6: NEVER

不能在事务中运行。假设DemoServiceA.demoMethodA的事务级别是REQUIRED, 而DemoServiceB.demoMethodB的事务级别是NEVER ,

那么DemoServiceB.demoMethodB就要抛出异常了。

7: NESTED

理解Nested的关键是savepoint。他与REQUIRES_NEW的区别是,REQUIRES_NEW另起一个事务,将会与他的父事务相互独立,

而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。

猜你喜欢

转载自blog.csdn.net/dghkgjlh/article/details/86479244