在 TransactionProxyFactoryBean 上有 setTransactionAttributeSource()与 setTransactionAttributes()方法,它们是用来设定交易属性的策略实例。
org.springframework.transaction.interceptor.TransactionAttributeSource 介面 上有一 个 getTransactionAttribute()方法,您可以根据传递给它的 Method 实例与 Class 实例,决定 该返回一个什么内容的 org.springframework.transaction.interceptor.TransactionAttribute 实例,一个最简单 的 TransactionAttributeSource 实作是 org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource, 对于每一个方法呼叫都会应用交易,它会返回的 TransactionAttribute 实例之预设传播行为是 PROPAGATION_REQUIRED, 隔离层级为 ISOLATION_DEFAULE。
一个应用的例子如下所示:
... <bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor. →?MatchAlwaysTransactionAttributeSource"/> <bean id="userDAOProxy" class="org.springframework.transaction. →?interceptor.TransactionProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <ref bean="transactionAttributeSource"/> </property> </bean> ...
您可以使用 org.springframework.transaction.interceptor.DefaultTransactionAttribute, 并设置自己的交易策略,之后将之设定给 TransactionAttributeSource,例如:
... <bean id="myTransactionAttribute" class="org.springframework.transaction. →?interceptor.DefaultTransactionAttribute"> <property name="propagationBehaviorName"> <value>PROPAGATION_REQUIRES_NEW</value> </property> <property name="isolationLevelName"> <value>ISOLATION_REPEATABLE_READ</value> </property> </bean> <bean id="transactionAttributeSource" class="org.springframework.transaction. →?interceptor.MatchAlwaysTransactionAttributeSource"> <property name="transactionAttribute"> <ref bean="myTransactionAttribute"/> </property> </bean> <bean id="userDAOProxy" class="org.springframework.transaction. →?interceptor.TransactionProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <ref bean="transactionAttributeSource"/> </property> </bean> ...
可以使用 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 来 指定某些方法要应用交易,以及要应用的交易策略,例如:
... <bean id="transactionAttributeSource" class="org.springframework.transaction. →?interceptor.NameMatchTransactionAttributeSource"> <property name="properties"> <props> <prop key="insert*"> PROPAGATION_REQUIRES_NEW </prop> </props> </property> </bean> <bean id="userDAOProxy" class="org.springframework.transaction. →?interceptor.TransactionProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <ref bean="transactionAttributeSource"/> </property> </bean> ...
在 NameMatchTransactionAttributeSource 的"properties"属性上,可以指定方法名称与交易策 略,方法名称的 指定可以指定全名,也可以使用 Wildcard 来指定,例如上面的指定中,只要方 法名称以 insert 为开头的都会应用相对应的交易策略。
在指定交易策略时,指定的格式如下: 传播行为,隔离层级,唯读,+例外, -例外 除了传播行为一定要设置之外,其它都可选择性的设置,中间以逗号区隔,例如:
PROPAGATION_REQUIRED,readOnly,-MyCheckedException
MyCheckedException 前面加上"-"时,表示发生指定例外时撤消操作,如果前面加上"+",表示 发生例外时立即提交。
在比较简单的设置中,可以仅设置 TransactionProxyFactoryBean,并在它的 "transactionAttributes"属性上直接设置要应用交易的方法及交易策略,例如:
... <bean id="userDAOProxy" class="org.springframework.transaction. →?interceptor.TransactionProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED</prop> </props> </property> </bean> ...
您甚至也可以直接指定 TransactionInterceptor,以获得更多的控制,例如:
... <bean id="transactionInterceptor" class="org.springframework.transaction. →?interceptor.TransactionInterceptor"> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <value> onlyfun.caterpillar.UserDAO.insert*=PROPAGATION_REQUIRED </value> </property> </bean> <bean id="userDAOProxy" class="org.springframework.aop. →?framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target"> <ref bean="userDAO"/> </property> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean> ...
选择哪一种设定方式是需求的问题,您可以尝试在 DeclarativeTransactionDemo 专案的 Bean 定 义档上设定以上所介绍的方式,基于篇幅的限制,以上仅列出部份的设定内容。