博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 申明式事务之注解
阅读量:4049 次
发布时间:2019-05-25

本文共 6549 字,大约阅读时间需要 21 分钟。

– 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
{ 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; } }}
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() { ... }}
...
...

注意

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

JDBC DataSourceUtils

JPA EntityManagerFactoryUtils
Hibernate SessionFactoryUtils
JDO PersistenceManagerFactoryUtils

Java 配置例子

package shangbo.spring.transaction.jdbc.annotation2;import javax.sql.DataSource;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(DataSource dataSource) {		DataSourceTransactionManager txManager = new DataSourceTransactionManager();		txManager.setDataSource(dataSource);				return txManager;	}		@Bean	public BusinessService businessService(DataSource dataSource) {		BusinessService businessService = new DefaultBusinessService();		businessService.setDataSource(dataSource);				return businessService;	}	}

– 声 明:转载请注明出处
– Last Updated on 2017-06-12
– Written by ShangBo on 2017-06-12
– End

你可能感兴趣的文章
iOS 序列化与反序列化(runtime) 01
查看>>
iOS AFN 3.0版本前后区别 01
查看>>
iOS ASI和AFN有什么区别
查看>>
iOS QQ侧滑菜单(高仿)
查看>>
iOS 扫一扫功能开发
查看>>
iOS app之间的跳转以及传参数
查看>>
iOS __block和__weak的区别
查看>>
Android(三)数据存储之XML解析技术
查看>>
Spring JTA应用之JOTM配置
查看>>
spring JdbcTemplate 的若干问题
查看>>
Servlet和JSP的线程安全问题
查看>>
GBK编码下jQuery Ajax中文乱码终极暴力解决方案
查看>>
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>