Spring 申明式事务之注解

来源:互联网 发布:航空数据查询接口 编辑:程序博客网 时间:2024/06/06 10:05

– Start

一个简单的例子

package shangbo.spring.transaction.jdbc.annotation;public class Job {    private String jobId;    private String jobTitle;    private Integer minSalary;    private Integer maxSalary;    public String getJobId() {        return jobId;    }    public void setJobId(String jobId) {        this.jobId = jobId;    }    public String getJobTitle() {        return jobTitle;    }    public void setJobTitle(String jobTitle) {        this.jobTitle = jobTitle;    }    public Integer getMinSalary() {        return minSalary;    }    public void setMinSalary(Integer minSalary) {        this.minSalary = minSalary;    }    public Integer getMaxSalary() {        return maxSalary;    }    public void setMaxSalary(Integer maxSalary) {        this.maxSalary = maxSalary;    }    public String toString() {        return "Job[jobId=" + jobId + ", jobTitle=" + jobTitle + ", minSalary=" + minSalary + ", maxSalary=" + maxSalary + "]";    }}
package shangbo.spring.transaction.jdbc.annotation;import org.apache.commons.dbcp.BasicDataSource;public interface BusinessService {    Job getJob(String jobId);    void insertJob(Job job) throws Exception;    void updateJob(Job job) throws Exception;    void setDataSource(BasicDataSource dataSource);}
package shangbo.spring.transaction.jdbc.annotation;import java.sql.ResultSet;import java.sql.SQLException;import org.apache.commons.dbcp.BasicDataSource;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.transaction.annotation.Transactional;public class DefaultBusinessService implements BusinessService {    private JdbcTemplate jdbcTemplate;    @Transactional(readOnly = true)    public Job getJob(String jobId) {        String sql = "SELECT * FROM HR.JOBS WHERE JOB_ID = ?";        return jdbcTemplate.queryForObject(sql, new JobRowMapper(), jobId);    }    @Transactional(rollbackFor = Exception.class)    public void updateJob(Job job) throws Exception {        String sql = "UPDATE HR.JOBS SET JOB_TITLE=?, MIN_SALARY = ?, MAX_SALARY = ? WHERE JOB_ID = ?";        jdbcTemplate.update(sql, job.getJobTitle(), job.getMinSalary(), job.getMaxSalary(), job.getJobId());        // 测试回滚        // throw new Exception("test");    }    @Transactional(rollbackFor = Exception.class)    public void insertJob(Job job) throws Exception {        String sql = "INSERT INTO HR.JOBS VALUES (?, ?, ?, ?)";        jdbcTemplate.update(sql, job.getJobId(), job.getJobTitle(), job.getMinSalary(), job.getMaxSalary());        // 测试回滚        // throw new Exception("test");    }    public void setDataSource(BasicDataSource dataSource) {        this.jdbcTemplate = new JdbcTemplate(dataSource);    }    private static class JobRowMapper implements RowMapper<Job> {        public Job mapRow(ResultSet rs, int rowNum) throws SQLException {            Job job = new Job();            job.setJobId(rs.getString(1));            job.setJobTitle(rs.getString(2));            job.setMinSalary(rs.getInt(3));            job.setMaxSalary(rs.getInt(4));            return job;        }    }}
<?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:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">    <!-- 定义  dataSource -->    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />        <property name="username" value="hr" />        <property name="password" value="123456" />    </bean>    <!-- 定义 jdbc 事务管理器 -->    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"/>    </bean>    <!-- 开启事务管理 -->    <tx:annotation-driven transaction-manager="txManager"/>    <!-- 定义 businessService -->    <bean id="businessService" class="shangbo.spring.transaction.jdbc.annotation.DefaultBusinessService">        <property name="dataSource" ref="dataSource"/>    </bean></beans>
package shangbo.spring.transaction.jdbc.annotation;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {    public static void main(String[] args) throws Exception {        // 实例化 Spring IoC 容器        ApplicationContext context = new ClassPathXmlApplicationContext("example.xml", BusinessService.class);        // 从容器中获得 BusinessService 的实例        BusinessService service = context.getBean(BusinessService.class);        // 使用 BusinessService        // 插入 job        Job job = newJob();        // service.insertJob(job);        // 更新 job        service.updateJob(job);        // 查询 job        System.out.println(service.getJob("IT"));    }    private static Job newJob() {        Job job = new Job();        job.setJobId("IT");        job.setJobTitle("IT Engineer");        job.setMinSalary(2);        job.setMaxSalary(100000);        return job;    }}

Spring 事务

从这个例子可以看到,使用 Spring 事务非常简单,其实,Spring 本身并不提供事务功能,Spring 只是对其他提供事务的技术进行了封装,提供了一个统一的使用方式,Spring 支持如下事务。

DataSourceTransactionManager – 对 JDBC 事务封装
HibernateTransactionManager – 对 Hibernate 事务封装
JpaTransactionManager – 对 JPA(Java Persistence API) 事务封装
JdoTransactionManager – 对 JDO(Java Data Objects) 事务封装
JtaTransactionManager – 对 JTA(Java Transaction API) 事务封装
JmsTransactionManager – 对 JMS(Java Message Service) 事务封装
CciLocalTransactionManager – 对 CCI(Common Client Interface) 事务封装

如果你需要在一个事务中同步多个资源,如:同时操作数据库和 JMS,你需要使用 JTA 事务,但是 JTA 事务需要应用服务器的支持,如 Weblogic, WebSphere, JBoss 等,不过现在的程序很少使用应用服务器了,如果你还有这方面的需求,你可以使用独立的事务产品, 如:JOTM,atomikos

事务设置

@Transactional 支持如下属性,允许我们对事务进行设置。

value – 指定事务管理器,配置了多个事务管理器时使用。
propagation – 事务传播属性
isolation – 事务隔离级别
readOnly – 是否为只读属性,查询时,我们可以设置 readOnly=true
timeout – 事务超时
rollbackFor – 指定需要回滚的异常类,特别注意默认只有 Error 和 RuntimeException 时自动回滚
rollbackForClassName – 指定需要回滚的异常类名
noRollbackFor – 指定不需要回滚的异常类
noRollbackForClassName – 指定不需要回滚的异常类名

配置多个事务管理器

public class TransactionalService {    @Transactional("order")    public void setSomething(String name) { ... }    @Transactional("account")    public void doSomething() { ... }}<tx:annotation-driven/><bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    ...    <qualifier value="order"/></bean><bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    ...    <qualifier value="account"/></bean>

注意

在 Spring 事务中,我们需要通过 Spring 提供了类(如:JdbcTemplate)访问数据库,如果你需要获取数据库连接自己访问数据库,我们不能通过 dataSource.getConnection(),而是需要通过 DataSourceUtils.getConnection(dataSource)获取数据库连接。

JDBC DataSourceUtils
JPA EntityManagerFactoryUtils
Hibernate SessionFactoryUtils
JDO PersistenceManagerFactoryUtils

Java 配置例子

package shangbo.spring.transaction.jdbc.annotation2;import org.apache.commons.dbcp.BasicDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;@Configuration@EnableTransactionManagement // 开启事务管理public class AppConfig {    @Bean    public BasicDataSource dataSource() {        BasicDataSource dataSource = new BasicDataSource();        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");        dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");        dataSource.setUsername("hr");        dataSource.setPassword("123456");        return dataSource;    }    @Bean    public DataSourceTransactionManager txManager() {        DataSourceTransactionManager txManager = new DataSourceTransactionManager();        txManager.setDataSource(dataSource());        return txManager;    }    @Bean    public BusinessService businessService() {        BusinessService businessService = new DefaultBusinessService();        businessService.setDataSource(dataSource());        return businessService;    }}

更多参见:Spring Framework 精萃
– 声 明:转载请注明出处
– Last Updated on 2017-06-12
– Written by ShangBo on 2017-06-12
– End

原创粉丝点击