Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
带水的鱼儿
spring-framework
提交
da9ee06e
S
spring-framework
项目概览
带水的鱼儿
/
spring-framework
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
da9ee06e
编写于
5月 30, 2021
作者:
S
Sam Brannen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve @Transactional docs regarding method visibility
Closes gh-27003
上级
4c28266e
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
88 addition
and
43 deletion
+88
-43
spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
...springframework/transaction/annotation/Transactional.java
+17
-14
src/docs/asciidoc/data-access.adoc
src/docs/asciidoc/data-access.adoc
+71
-29
未找到文件。
spring-tx/src/main/java/org/springframework/transaction/annotation/Transactional.java
浏览文件 @
da9ee06e
/*
* Copyright 2002-202
0
the original author or authors.
* Copyright 2002-202
1
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -29,10 +29,13 @@ import org.springframework.transaction.TransactionDefinition;
/**
* Describes a transaction attribute on an individual method or on a class.
*
* <p>At the class level, this annotation applies as a default to all methods of
* the declaring class and its subclasses. Note that it does not apply to ancestor
* classes up the class hierarchy; methods need to be locally redeclared in order
* to participate in a subclass-level annotation.
* <p>When this annotation is declared at the class level, it applies as a default
* to all methods of the declaring class and its subclasses. Note that it does not
* apply to ancestor classes up the class hierarchy; inherited methods need to be
* locally redeclared in order to participate in a subclass-level annotation. For
* details on method visibility constraints, consult the
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction">Transaction Management</a>
* section of the reference manual.
*
* <p>This annotation type is generally directly comparable to Spring's
* {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}
...
...
@@ -46,14 +49,14 @@ import org.springframework.transaction.TransactionDefinition;
* consult the {@link org.springframework.transaction.TransactionDefinition} and
* {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
*
* <p>This annotation commonly works with thread-bound transactions managed by
* <p>This annotation commonly works with thread-bound transactions managed by
a
* {@link org.springframework.transaction.PlatformTransactionManager}, exposing a
* transaction to all data access operations within the current execution thread.
* <b>Note: This does NOT propagate to newly started threads within the method.</b>
*
* <p>Alternatively, this annotation may demarcate a reactive transaction managed
* by {@link org.springframework.transaction.ReactiveTransactionManager} which
* uses the Reactor context instead of thread-local
attribut
es. As a consequence,
* by
a
{@link org.springframework.transaction.ReactiveTransactionManager} which
* uses the Reactor context instead of thread-local
variabl
es. As a consequence,
* all participating data access operations need to execute within the same
* Reactor context in the same reactive pipeline.
*
...
...
@@ -94,12 +97,12 @@ public @interface Transactional {
String
transactionManager
()
default
""
;
/**
* Defines zero (0) or more transaction labels.
Labels may be used to
*
describe a transaction and they can be evaluated by individual transaction
*
manager. Labels may serve a solely descriptive purpose or map to
* pre-defined transaction manager-specific options.
* <p>See the d
escrip
tion of the actual transaction manager implementation
* how it evaluates transaction labels.
* Defines zero (0) or more transaction labels.
*
<p>Labels may be used to describe a transaction, and they can be evaluated
*
by individual transaction managers. Labels may serve a solely descriptive
* p
urpose or map to p
re-defined transaction manager-specific options.
* <p>See the d
ocumenta
tion of the actual transaction manager implementation
*
for details on
how it evaluates transaction labels.
* @since 5.3
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#getLabels()
*/
...
...
src/docs/asciidoc/data-access.adoc
浏览文件 @
da9ee06e
...
...
@@ -837,9 +837,9 @@ that test drives the configuration shown earlier:
public
final
class
Boot
{
public
static
void
main
(
final
String
[]
args
)
throws
Exception
{
ApplicationContext
ctx
=
new
ClassPathXmlApplicationContext
(
"context.xml"
,
Boot
.
class
);
FooService
fooService
=
(
FooService
)
ctx
.
getBean
(
"fooService"
);
fooService
.
insertFoo
(
new
Foo
());
ApplicationContext
ctx
=
new
ClassPathXmlApplicationContext
(
"context.xml"
);
FooService
fooService
=
ctx
.
getBean
(
FooService
.
class
);
fooService
.
insertFoo
(
new
Foo
());
}
}
----
...
...
@@ -1314,18 +1314,22 @@ Consider the following class definition:
@Transactional
public class DefaultFooService implements FooService {
@Override
public Foo getFoo(String fooName) {
// ...
}
@Override
public Foo getFoo(String fooName, String barName) {
// ...
}
@Override
public void insertFoo(Foo foo) {
// ...
}
@Override
public void updateFoo(Foo foo) {
// ...
}
...
...
@@ -1356,11 +1360,13 @@ Consider the following class definition:
}
----
Used at the class level as above, the annotation indicates a default for all public methods
of the declaring class (as well as its subclasses). Alternatively, each method can
get annotated individually. Note that a class-level annotation does not apply to
ancestor classes up the class hierarchy; in such a scenario, methods need to be
locally redeclared in order to participate in a subclass-level annotation.
Used at the class level as above, the annotation indicates a default for all methods of
the declaring class (as well as its subclasses). Alternatively, each method can be
annotated individually. See <<transaction-declarative-annotations-method-visibility>> for
further details on which methods Spring considers transactional. Note that a class-level
annotation does not apply to ancestor classes up the class hierarchy; in such a scenario,
inherited methods need to be locally redeclared in order to participate in a
subclass-level annotation.
When a POJO class such as the one above is defined as a bean in a Spring context,
you can make the bean instance transactional through an `@EnableTransactionManagement`
...
...
@@ -1390,7 +1396,8 @@ In XML configuration, the `<tx:annotation-driven/>` tag provides similar conveni
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/><!-- a TransactionManager is still required --> <1>
<!-- a TransactionManager is still required -->
<tx:annotation-driven transaction-manager="txManager"/> <1>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- (this dependency is defined somewhere else) -->
...
...
@@ -1405,7 +1412,7 @@ In XML configuration, the `<tx:annotation-driven/>` tag provides similar conveni
TIP: You can omit the `transaction-manager` attribute in the `<tx:annotation-driven/>`
tag if the bean name of the `TransactionManager` that you want to wire in has the name
,
tag if the bean name of the `TransactionManager` that you want to wire in has the name
`transactionManager`. If the `TransactionManager` bean that you want to dependency-inject
has any other name, you have to use the `transaction-manager` attribute, as in the
preceding example.
...
...
@@ -1420,18 +1427,22 @@ programming arrangements as the following listing shows:
@Transactional
public class DefaultFooService implements FooService {
@Override
public Publisher<Foo> getFoo(String fooName) {
// ...
}
@Override
public Mono<Foo> getFoo(String fooName, String barName) {
// ...
}
@Override
public Mono<Void> insertFoo(Foo foo) {
// ...
}
@Override
public Mono<Void> updateFoo(Foo foo) {
// ...
}
...
...
@@ -1467,17 +1478,47 @@ Reactive Streams cancellation signals. See the <<tx-prog-operator-cancel>> secti
"Using the TransactionOperator" for more details.
[[transaction-declarative-annotations-method-visibility]]
.Method visibility and `@Transactional`
****
When you use proxies, you should apply the `@Transactional` annotation only to methods
with public visibility. If you do annotate protected, private or package-visible
methods with the `@Transactional` annotation, no error is raised, but the annotated
method does not exhibit the configured transactional settings. If you need to annotate
non-public methods, consider using AspectJ (described later).
****
[NOTE]
====
When you use transactional proxies with Spring'
s
standard
configuration
,
you
should
apply
the
`@
Transactional
`
annotation
only
to
methods
with
`
public
`
visibility
.
If
you
do
annotate
`
protected
`,
`
private
`,
or
package
-
visible
methods
with
the
`@
Transactional
`
annotation
,
no
error
is
raised
,
but
the
annotated
method
does
not
exhibit
the
configured
transactional
settings
.
If
you
need
to
annotate
non
-
public
methods
,
consider
the
tip
in
the
following
paragraph
for
class
-
based
proxies
or
consider
using
AspectJ
compile
-
time
or
load
-
time
weaving
(
described
later
).
When
using
`@
EnableTransactionManagement
`
in
a
`@
Configuration
`
class
,
`
protected
`
or
package
-
visible
methods
can
also
be
made
transactional
for
class
-
based
proxies
by
registering
a
custom
`
transactionAttributeSource
`
bean
like
in
the
following
example
.
Note
,
however
,
that
transactional
methods
in
interface
-
based
proxies
must
always
be
`
public
`
and
defined
in
the
proxied
interface
.
[
source
,
java
,
indent
=
0
,
subs
=
"verbatim,quotes"
]
----
/**
*
Register
a
custom
AnnotationTransactionAttributeSource
with
the
*
publicMethodsOnly
flag
set
to
false
to
enable
support
for
*
protected
and
package
-
private
@
Transactional
methods
in
*
class
-
based
proxies
.
*
*
@
see
ProxyTransactionManagementConfiguration
#
transactionAttributeSource
()
*/
@
Bean
TransactionAttributeSource
transactionAttributeSource
()
{
return
new
AnnotationTransactionAttributeSource
(
false
);
}
----
The
_Spring
TestContext
Framework_
supports
non
-
private
`@
Transactional
`
test
methods
by
default
.
See
<<
testing
.
adoc
#
testcontext
-
tx
,
Transaction
Management
>>
in
the
testing
chapter
for
examples
.
====
You
can
apply
the
`@
Transactional
`
annotation
to
an
interface
definition
,
a
method
on an interface, a class definition, or a
public
method on a class. However, the
on
an
interface
,
a
class
definition
,
or
a
method
on
a
class
.
However
,
the
mere
presence
of
the
`@
Transactional
`
annotation
is
not
enough
to
activate
the
transactional
behavior
.
The
`@
Transactional
`
annotation
is
merely
metadata
that
can
be
consumed
by
some
runtime
infrastructure
that
is
`@
Transactional
`-
aware
and
that
...
...
@@ -1499,12 +1540,13 @@ the proxy are intercepted. This means that self-invocation (in effect, a method
the
target
object
calling
another
method
of
the
target
object
)
does
not
lead
to
an
actual
transaction
at
runtime
even
if
the
invoked
method
is
marked
with
`@
Transactional
`.
Also
,
the
proxy
must
be
fully
initialized
to
provide
the
expected
behavior
,
so
you
should
not
rely on this feature in your initialization code (that is, `@PostConstruct`).
rely
on
this
feature
in
your
initialization
code
--
for
example
,
in
a
`@
PostConstruct
`
method
.
Consider using
of
AspectJ mode (see the `mode` attribute in the following table) if you
expect self-invocations to be wrapped with transactions as well. In this case, there
no
proxy in the first place. Instead, the target class is woven (that is, its byte code is
modified) to turn `@Transactional` into
runtime behavior on any kind of method.
Consider
using
AspectJ
mode
(
see
the
`
mode
`
attribute
in
the
following
table
)
if
you
expect
self
-
invocations
to
be
wrapped
with
transactions
as
well
.
In
this
case
,
there
is
no
proxy
in
the
first
place
.
Instead
,
the
target
class
is
woven
(
that
is
,
its
byte
code
is
modified
)
to
support
`@
Transactional
`
runtime
behavior
on
any
kind
of
method
.
[[
tx
-
annotation
-
driven
-
settings
]]
.
Annotation
driven
transaction
settings
...
...
@@ -1557,14 +1599,14 @@ NOTE: The `proxy-target-class` attribute controls what type of transactional pro
created
for
classes
annotated
with
the
`@
Transactional
`
annotation
.
If
`
proxy
-
target
-
class
`
is
set
to
`
true
`,
class
-
based
proxies
are
created
.
If
`
proxy
-
target
-
class
`
is
`
false
`
or
if
the
attribute
is
omitted
,
standard
JDK
interface-based proxies are created. (See <<core.adoc#aop-proxying
>> for a discussion of the
different proxy types.)
interface
-
based
proxies
are
created
.
(
See
<<
core
.
adoc
#
aop
-
proxying
,
Proxying
Mechanisms
>>
for
a
discussion
of
the
different
proxy
types
.)
NOTE: `@EnableTransactionManagement` and `<tx:annotation-driven/>` look
s
for
NOTE
:
`@
EnableTransactionManagement
`
and
`<
tx
:
annotation
-
driven
/>`
look
for
`@
Transactional
`
only
on
beans
in
the
same
application
context
in
which
they
are
defined
.
This
means
that
,
if
you
put
annotation
-
driven
configuration
in
a
`
WebApplicationContext
`
for
a
`
DispatcherServlet
`,
it
checks
for
`@
Transactional
`
beans
only
in
your
controllers
and not your services. See <<web.adoc#mvc-servlet, MVC>> for more information.
and
not
in
your
services
.
See
<<
web
.
adoc
#
mvc
-
servlet
,
MVC
>>
for
more
information
.
The
most
derived
location
takes
precedence
when
evaluating
the
transactional
settings
for
a
method
.
In
the
case
of
the
following
example
,
the
`
DefaultFooService
`
class
is
...
...
@@ -1612,8 +1654,8 @@ precedence over the transactional settings defined at the class level.
=====
`@
Transactional
`
Settings
The
`@
Transactional
`
annotation
is
metadata
that
specifies
that
an
interface
,
class
,
or method must have transactional semantics (for example, "
`
start a brand new read-only
transaction when this method is invoked, suspending any existing transaction
`
").
or
method
must
have
transactional
semantics
(
for
example
,
"start a brand new read-only
transaction when this method is invoked, suspending any existing transaction"
).
The
default
`@
Transactional
`
settings
are
as
follows
:
*
The
propagation
setting
is
`
PROPAGATION_REQUIRED
.`
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录