Spring事务管理

事务的基本原理

        Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交,那在没有Spring帮我们管理事务之前,我们要怎么做。

Connection conn = DriverManager.getConnection();
try {  
    conn.setAutoCommit(false);  //将自动提交设置为false                         
    执行CRUD操作 
    conn.commit();      //当两个操作成功后手动提交  
} catch (Exception e) {  
    conn.rollback();    //一旦其中一个操作出错都将回滚,所有操作都不成功
    e.printStackTrace();  
} finally {
    conn.colse();
}

       事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误。事务的出现是为了确保数据的完整性和一致性,在目前企业级应用开发中,事务管理是必不可少的。

Spring事务管理

Spring事务管理的核心接口是PlatformTransactionManager

       事务管理器接口通过getTransaction(TransactionDefinition definition)方法根据指定的传播行为返回当前活动的事务或创建一个新的事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。在TransactionDefinition接口中定义了它自己的传播行为和隔离级别。

除去常量,主要的方法有:

int getIsolationLevel();// 返回事务的隔离级别
String getName();// 返回事务的名称
int getPropagationBehavior();// 返回事务的传播行为
int getTimeout();  // 返回事务必须在多少秒内完成
boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的

@Transactional的使用

  • rollbackFor 属性:用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
  • noRollbackFor 属性:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。

回滚规则:

Spring事务的传播属性

由上图可知,Spring定义了7个以PROPAGATION_开头的常量表示它的传播属性。

Spring事务的隔离级别

调用PlatformTransactionManager接口的getTransaction()的方法得到的是TransactionStatus接口的一个实现
TransactionStatus接口

主要的方法有:

void flush();//如果适用的话,这个方法用于刷新底层会话中的修改到数据库,例如,所有受影响的Hibernate/JPA会话。
boolean hasSavepoint(); // 是否有恢复点
boolean isCompleted();// 是否已完成
boolean isNewTransaction(); // 是否是新的事务
boolean isRollbackOnly(); // 是否为只回滚
void setRollbackOnly();  // 设置为只回滚

可以看出返回的结果是一些事务的状态,可用来检索事务的状态信息。

编程式事务:

        所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理。管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

声明式事务:

        管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

       显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。

      声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

配置类:

@Configuration
@ComponentScan("com.enjoy.cap11")
@EnableTransactionManagement  //开启事务管理功能,对@Transactional起作用  EnableXXXX
public class Cap11MainConfig {
	//创建数据源
	@Bean
	public DataSource dataSource() throws PropertyVetoException{
		//这个c3p0封装了JDBC, dataSource接口的实现
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser("root");
		dataSource.setPassword("123456");
		dataSource.setDriverClass("com.mysql.jdbc.Driver");
		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/t_test");
		return dataSource;
	}
	
	//jdbcTemplate模板能简化增删改查的操作
	@Bean
	public JdbcTemplate jdbcTemplate() throws PropertyVetoException{
		return new JdbcTemplate(dataSource());
	}
	
	//注册事务管理器
	@Bean
	public PlatformTransactionManager platformTransactionManager() throws PropertyVetoException{
		return new DataSourceTransactionManager(dataSource());
	}
}

service层:

package com.enjoy.cap11.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.enjoy.cap11.dao.OrderDao;

@Service
public class OrderService {
    @Autowired
	private OrderDao orderDao;
    @Transactional
    public void addOrder(){
    	orderDao.insert();
    	System.out.println("操作完成.........");
    	
    	int a = 1/0;
    }
}

Dao层:

package com.enjoy.cap11.dao;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class OrderDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;
	//操作数据的方法
	public void insert(){
		String sql = "insert into `cst_customer` (cust_name) values(?)";
		jdbcTemplate.update(sql,"xiaoyan");
	}
}

测试类:

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import com.enjoy.cap10.aop.Calculator;
import com.enjoy.cap10.config.Cap10MainConfig;
import com.enjoy.cap11.config.Cap11MainConfig;
import com.enjoy.cap11.service.OrderService;
import com.enjoy.cap7.config.Cap7MainConfigOfLifeCycle;
import com.enjoy.cap8.bean.Bird;
import com.enjoy.cap8.config.Cap8MainConfig;
import com.enjoy.cap9.bean.Moon;
import com.enjoy.cap9.bean.Sun;
import com.enjoy.cap9.config.Cap9MainConfig;
import com.enjoy.cap9.dao.TestDao;
import com.enjoy.cap9.service.TestService;

public class Cap11Test {
	@Test
	public void test01(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap11MainConfig.class);
		
		OrderService bean = app.getBean(OrderService.class);
		bean.addOrder();
		app.close();
	}
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值