Spring 对事务管理的支持

本文内容纲要:Spring 对事务管理的支持

1、Spring对事务管理的支持

Spring为事务管理提供了一致的编程模板,在高层次建立了统一的事务抽象。也就是说,不管选择Spring JDBC、Hibernate 、JPA 还是iBatis,Spring都让我们可以用统一的编程模型进行事务管理。

在Spring事务管理SPI(Service Provider Interface)的抽象层主要包括3个接口,分别是PlatformTransactionManager、TransactionDefinition和TransactionStatus。TransactionDefinition用于描述事务的隔离级别、超时时间、是否为只读事务和事务传播规则等控制事务具体行为的事务属性,这些事务属性可以通过XML配置或注解描述提供,也可以通过手工编程的方式设置。PlatformTransactionManager根据TransactionDefinition提供的事务属性配置信息,创建事务,并用TransactionStatus描述这个激活事务的状态。

1)Spring JDBC 和iBatis

基于数据源的数据管理器

<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close"

p:driverClassName="${jdbc.driverClassName}"

p:url="${jdbc.url}"

p:username="${jdbc.username}"

p:password="${jdbc.password}"/>

<bean id="transactionManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager"

p:dataSource-ref="dataSource"/>

2)JPA

JAP事务管理器配置

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"

p:dataSource-ref="dataSource"/>

...

<bean id="transactionManger" class="org.springframework.orm.jpa.JpaTransactionManager"

p:entityManagerFacotry-ref="entityManagerFactory"/>

3)Hibernate

Hibernate3.0事务管理器配置

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"

p:dataSource-ref="dataSource"

p:mappingResources="classpath:bbtForum.hbm.xml">

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.generate_statistics">true</prop>

</props>

</property>

</bean>

4)JTA

JTA事务管理器

<jee:jndi-lookup id="accountDs" jndi-name="java:comp/env/jdbc/account"/>

<jee:jndi-lookup id="orderDs" jndi-name="java:comp/env/jdbc/account"/>

<bean id="transactionManager"

class="org.springframework.transaction.jta.JtaTransactionManager"/>

2、编程式事务管理

Spring事务管理提供了模板类org.springframework.transaction.support.TransactionTemplate,以满足一些特殊场合的需要。

package com.baobaotao.service;

import org.springframework.transaction.TransactionStatus;

import org.springframework.transaction.support.TransactionCallbackWithoutResult;

import org.springframework.transaction.support.TransactionTemplate;

import com.baobaotao.dao.ForumDao;

import com.baobaotao.domain.Forum;

public class ForumService1 {

private ForumDao forumDao;

//通过IoC注入

private TransactionTemplate template;

public void addForum(final Forum forum) {

template.execute(new TransactionCallbackWithoutResult() {

protected void doInTransactionWithoutResult(TransactionStatus status) {

//需要在事务环境中执行的代码

forumDao.addForum(forum);

}

});

}

public void setForumDao(ForumDao forumDao) {

this.forumDao = forumDao;

}

public void setTemplate(TransactionTemplate template) {

this.template = template;

}

}

3、使用XML配置声明式事务

Spring的声明式事务管理是通过Spring AOP实现的,通过事务的声明性信息,Spring负责将事务管理增强逻辑动态织入到业务方法相应连接点中。这些逻辑包括获取线程绑定资源、开始事务、提交/回滚事务、进行异常转换和处理等工作。

BbtForum接口:

package com.yyq.service;

import com.yyq.domain.Forum;

import com.yyq.domain.Topic;

public interface BbtForum {

void addTopic(Topic topic) throws Exception;

void updateForum(Forum forum);

Forum getForum(int forumId);

int getForumNum();

}

BbtForumImpl实现类:

package com.yyq.service.impl;

import com.yyq.dao.ForumDao;

import com.yyq.dao.PostDao;

import com.yyq.dao.TopicDao;

import com.yyq.domain.Forum;

import com.yyq.domain.Topic;

import com.yyq.service.BbtForum;

public class BbtForumImpl implements BbtForum {

private ForumDao forumDao;

private TopicDao topicDao;

private PostDao postDao;

public void addTopic(Topic topic) throws Exception {

topicDao.addTopic(topic);

// if(true) throw new PessimisticLockingFailureException("fail");

postDao.addPost(topic.getPost());

}

public Forum getForum(int forumId) {

return forumDao.getForum(forumId);

}

public void updateForum(Forum forum) {

forumDao.updateForum(forum);

}

public int getForumNum() {

return forumDao.getForumNum();

}

public void setForumDao(ForumDao forumDao) {

this.forumDao = forumDao;

}

public void setPostDao(PostDao postDao) {

this.postDao = postDao;

}

public void setTopicDao(TopicDao topicDao) {

this.topicDao = topicDao;

}

}

Dao和Datasource配置文件applicationContext-dao.xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:property-placeholder location="classpath:jdbc.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close"

p:driverClassName="${jdbc.driverClassName}"

p:url="${jdbc.url}"

p:username="${jdbc.username}"

p:password="${jdbc.password}"/>

<bean id="jdbcTemplate"

class="org.springframework.jdbc.core.JdbcTemplate"

p:dataSource-ref="dataSource"/>

<bean id="abstracDao" abstract="true" p:jdbcTemplate-ref="jdbcTemplate"/>

<bean id="forumDao" parent="abstracDao" class="com.yyq.dao.jdbc.ForumDaoImpl" />

<bean id="postDao" parent="abstracDao" class="com.yyq.dao.jdbc.PostDaoImpl"/>

<bean id="topicDao" parent="abstracDao" class="com.yyq.dao.jdbc.TopicDaoImpl"/>

</beans>

1)使用原始的TransactionProxyFactoryBean进行声明式事务配置:

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!--导入Dao和DataSource的配置文件-->

<import resource="applicationContext-dao.xml"/>

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"/>

</bean>

<!--需要实施事务增强的目标业务Bean-->

<bean id="bbtForumTarget" class="com.yyq.service.impl.BbtForumImpl"

p:forumDao-ref="forumDao"

p:topicDao-ref="topicDao"

p:postDao-ref="postDao"/>

<!--使用事务代理工程类为目标业务Bean提供事务增强-->

<bean id="bbtForum" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

p:transactionManager-ref="txManager"

p:target-ref="bbtForumTarget">

<property name="transactionAttributes">

<props>

<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>

<prop key="*">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

</beans>

测试方法:

import com.yyq.domain.Post;

import com.yyq.domain.Topic;

import com.yyq.service.BbtForum;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBbtForumPfb {

public static void main(String[] args) throws Throwable{

String configPath = "classpath:applicationContext-pfb.xml";

ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);

BbtForum bbtForum = ctx.getBean("bbtForum",BbtForum.class);

System.out.println("begin........");

Topic topic = new Topic();

topic.setTopicTitle("Title -pfb");

Post post = new Post();

post.setPostText("post content -pfb");

topic.setPost(post);

bbtForum.addTopic(topic);

System.out.println("end........");

}

}

2)基于tx/aop命名空间的配置:

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<!--导入Dao和DataSource的配置文件-->

<import resource="classpath:applicationContext-dao.xml"/>

<!--声明事务管理器-->

<bean id="txManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager"

p:dataSource-ref="dataSource"/>

<!--不再需要为了事务AOP增强的实施而改名换姓-->

<bean id="bbtForum"

class="com.yyq.service.impl.BbtForumImpl"

p:forumDao-ref="forumDao"

p:topicDao-ref="topicDao"

p:postDao-ref="postDao"/>

<!--使用强大的切点表达式语言轻松定义目标方法-->

<aop:config>

<!--通过aop定义事务增强切面-->

<aop:pointcut id="serviceMethod" expression="execution(* com.yyq.service.*Forum.*(..))"/>

<!--引用事务增强-->

<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>

</aop:config>

<!--事务增强-->

<tx:advice id="txAdvice" transaction-manager="txManager">

<tx:attributes>

<!--事务属性定义-->

<tx:method name="get*" read-only="false"/>

<tx:method name="add*" rollback-for="PessimisticLockingFailureException"/>

<tx:method name="update*"/>

</tx:attributes>

</tx:advice>

</beans>

测试方法:

import com.yyq.domain.Post;

import com.yyq.domain.Topic;

import com.yyq.service.BbtForum;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBbtForumTx {

public static void main(String[] args) throws Throwable{

String configPath = "classpath:applicationContext-tx.xml";

ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);

BbtForum bbtForum = ctx.getBean(BbtForum.class);

System.out.println("begin........");

Topic topic = new Topic();

topic.setTopicTitle("Title Tx-");

Post post = new Post();

post.setPostText("post content -Tx");

topic.setPost(post);

bbtForum.addTopic(topic);

System.out.println("end........");

}

}

4、使用注解配置声明式事务

使用@Transaction注解声明事务,可以应用于接口定义和接口方法、类定义和类的public方法上。

使用@Transaction注解的业务类:

@Transactional

public class BbtForumImpl implements BbtForum {

private ForumDao forumDao;

private TopicDao topicDao;

private PostDao postDao;

public void addTopic(Topic topic) throws Exception {

topicDao.addTopic(topic);

//if(true) throw new PessimisticLockingFailureException("fail");

postDao.addPost(topic.getPost());

}

public Forum getForum(int forumId) {

return forumDao.getForum(forumId);

}

public void updateForum(Forum forum) {

forumDao.updateForum(forum);

}

....

applicationContext-anno.xml:使事务注解生效

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:tx="http://www.springframework.org/schema/tx"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<import resource="classpath:applicationContext-dao.xml"/>

<!--由于该Bean实现类标注了@Transaction,所以将会被注解驱动自动织入事务-->

<bean id="bbtForum"

class="com.yyq.service.impl.BbtForumImpl"

p:forumDao-ref="forumDao"

p:topicDao-ref="topicDao"

p:postDao-ref="postDao"/>

<bean id="txManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager"

p:dataSource-ref="dataSource"/>

<!--对标注@Transaction注解的Bean进行加工处理,以织入事务管理切面-->

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

</beans>

本文内容总结:Spring 对事务管理的支持

原文链接:https://www.cnblogs.com/yangyquin/p/5583158.html

以上是 Spring 对事务管理的支持 的全部内容, 来源链接: utcz.com/z/362719.html

回到顶部